QCamera3Channel.cpp revision d897e24270f74b8266a37e01a1dd2f4797b13258
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 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 m_postprocessor.start(mMemory, index, this); 1018 1019 ALOGD("%s: Post-process started", __func__); 1020 if(pInputBuffer) { 1021 ALOGD("%s: Issue call to reprocess", __func__); 1022 m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel); 1023 } 1024 return rc; 1025} 1026 1027/*=========================================================================== 1028 * FUNCTION : dataNotifyCB 1029 * 1030 * DESCRIPTION: Channel Level callback used for super buffer data notify. 1031 * This function is registered with mm-camera-interface to handle 1032 * data notify 1033 * 1034 * PARAMETERS : 1035 * @recvd_frame : stream frame received 1036 * userdata : user data ptr 1037 * 1038 * RETURN : none 1039 *==========================================================================*/ 1040void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1041 void *userdata) 1042{ 1043 ALOGV("%s: E\n", __func__); 1044 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 1045 1046 if (channel == NULL) { 1047 ALOGE("%s: invalid channel pointer", __func__); 1048 return; 1049 } 1050 1051 if(channel->m_numStreams != 1) { 1052 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 1053 return; 1054 } 1055 1056 1057 if(channel->mStreams[0] == NULL) { 1058 ALOGE("%s: Error: Invalid Stream object",__func__); 1059 return; 1060 } 1061 1062 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 1063 1064 ALOGV("%s: X\n", __func__); 1065 return; 1066} 1067 1068 1069int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 1070 buffer_handle_t **buffers) 1071{ 1072 int rc = 0; 1073 cam_stream_type_t streamType; 1074 cam_format_t streamFormat; 1075 1076 ALOGV("%s: E",__func__); 1077 rc = QCamera3PicChannel::initialize(); 1078 if (rc < 0) { 1079 ALOGE("%s: init failed", __func__); 1080 return rc; 1081 } 1082 1083 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 1084 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 1085 streamFormat = CAM_FORMAT_YUV_420_NV21; 1086 } else { 1087 //TODO: Fail for other types of streams for now 1088 ALOGE("%s: format is not BLOB", __func__); 1089 return -EINVAL; 1090 } 1091 /* Bookkeep buffer set because they go out of scope after register call */ 1092 mNumBufs = num_buffers; 1093 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 1094 if (mCamera3Buffers == NULL) { 1095 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 1096 return -ENOMEM; 1097 } 1098 for (size_t i = 0; i < num_buffers; i++) 1099 mCamera3Buffers[i] = buffers[i]; 1100 1101 ALOGV("%s: X",__func__); 1102 return rc; 1103} 1104 1105void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1106 QCamera3Stream *stream) 1107{ 1108 //TODO 1109 //Used only for getting YUV. Jpeg callback will be sent back from channel 1110 //directly to HWI. Refer to func jpegEvtHandle 1111 1112 //Got the yuv callback. Calling yuv callback handler in PostProc 1113 uint8_t frameIndex; 1114 mm_camera_super_buf_t* frame = NULL; 1115 if(!super_frame) { 1116 ALOGE("%s: Invalid Super buffer",__func__); 1117 return; 1118 } 1119 1120 if(super_frame->num_bufs != 1) { 1121 ALOGE("%s: Multiple streams are not supported",__func__); 1122 return; 1123 } 1124 if(super_frame->bufs[0] == NULL ) { 1125 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1126 __func__); 1127 return; 1128 } 1129 1130 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1131 if(frameIndex >= mNumBufs) { 1132 ALOGE("%s: Error, Invalid index for buffer",__func__); 1133 if(stream) { 1134 stream->bufDone(frameIndex); 1135 } 1136 return; 1137 } 1138 1139 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1140 if (frame == NULL) { 1141 ALOGE("%s: Error allocating memory to save received_frame structure.", 1142 __func__); 1143 if(stream) { 1144 stream->bufDone(frameIndex); 1145 } 1146 return; 1147 } 1148 *frame = *super_frame; 1149 1150 m_postprocessor.processData(frame); 1151 free(super_frame); 1152 return; 1153} 1154 1155QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1156{ 1157 int rc = 0; 1158 1159 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1160 ALOGE("%s: buffers not registered yet", __func__); 1161 return NULL; 1162 } 1163 1164 if(mMemory) { 1165 delete mMemory; 1166 mMemory = NULL; 1167 } 1168 mMemory = new QCamera3GrallocMemory(); 1169 if (mMemory == NULL) { 1170 return NULL; 1171 } 1172 1173 //Registering Jpeg output buffer 1174 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1175 delete mMemory; 1176 mMemory = NULL; 1177 return NULL; 1178 } 1179 1180 mYuvMemory = new QCamera3HeapMemory(); 1181 if (!mYuvMemory) { 1182 ALOGE("%s: unable to create metadata memory", __func__); 1183 return NULL; 1184 } 1185 1186 //Queue YUV buffers in the beginning mQueueAll = true 1187 rc = mYuvMemory->allocate(1, len, false); 1188 if (rc < 0) { 1189 ALOGE("%s: unable to allocate metadata memory", __func__); 1190 delete mYuvMemory; 1191 mYuvMemory = NULL; 1192 return NULL; 1193 } 1194 return mYuvMemory; 1195} 1196 1197void QCamera3PicChannel::putStreamBufs() 1198{ 1199 mMemory->unregisterBuffers(); 1200 delete mMemory; 1201 mMemory = NULL; 1202 1203 mYuvMemory->deallocate(); 1204 delete mYuvMemory; 1205 mYuvMemory = NULL; 1206} 1207 1208bool QCamera3PicChannel::isRawSnapshot() 1209{ 1210 return !(mJpegSettings->is_jpeg_format); 1211} 1212/*=========================================================================== 1213 * FUNCTION : getThumbnailSize 1214 * 1215 * DESCRIPTION: get user set thumbnail size 1216 * 1217 * PARAMETERS : 1218 * @dim : output of thumbnail dimension 1219 * 1220 * RETURN : none 1221 *==========================================================================*/ 1222void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1223{ 1224 dim = mJpegSettings->thumbnail_size; 1225} 1226 1227/*=========================================================================== 1228 * FUNCTION : getJpegQuality 1229 * 1230 * DESCRIPTION: get user set jpeg quality 1231 * 1232 * PARAMETERS : none 1233 * 1234 * RETURN : jpeg quality setting 1235 *==========================================================================*/ 1236int QCamera3PicChannel::getJpegQuality() 1237{ 1238 int quality = mJpegSettings->jpeg_quality; 1239 if (quality < 0) { 1240 quality = 85; //set to default quality value 1241 } 1242 return quality; 1243} 1244 1245/*=========================================================================== 1246 * FUNCTION : getJpegRotation 1247 * 1248 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1249 * 1250 * PARAMETERS : none 1251 * 1252 * RETURN : rotation information 1253 *==========================================================================*/ 1254int QCamera3PicChannel::getJpegRotation() { 1255 int rotation = mJpegSettings->jpeg_orientation; 1256 if (rotation < 0) { 1257 rotation = 0; 1258 } 1259 return rotation; 1260} 1261 1262void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf) 1263{ 1264 m_postprocessor.processPPMetadata(metadata_buf); 1265} 1266/*=========================================================================== 1267 * FUNCTION : getRational 1268 * 1269 * DESCRIPTION: compose rational struct 1270 * 1271 * PARAMETERS : 1272 * @rat : ptr to struct to store rational info 1273 * @num :num of the rational 1274 * @denom : denom of the rational 1275 * 1276 * RETURN : int32_t type of status 1277 * NO_ERROR -- success 1278 * none-zero failure code 1279 *==========================================================================*/ 1280int32_t getRational(rat_t *rat, int num, int denom) 1281{ 1282 if (NULL == rat) { 1283 ALOGE("%s: NULL rat input", __func__); 1284 return BAD_VALUE; 1285 } 1286 rat->num = num; 1287 rat->denom = denom; 1288 return NO_ERROR; 1289} 1290 1291/*=========================================================================== 1292 * FUNCTION : parseGPSCoordinate 1293 * 1294 * DESCRIPTION: parse GPS coordinate string 1295 * 1296 * PARAMETERS : 1297 * @coord_str : [input] coordinate string 1298 * @coord : [output] ptr to struct to store coordinate 1299 * 1300 * RETURN : int32_t type of status 1301 * NO_ERROR -- success 1302 * none-zero failure code 1303 *==========================================================================*/ 1304int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1305{ 1306 if(coord == NULL) { 1307 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1308 return BAD_VALUE; 1309 } 1310 float degF = atof(coord_str); 1311 if (degF < 0) { 1312 degF = -degF; 1313 } 1314 float minF = (degF - (int) degF) * 60; 1315 float secF = (minF - (int) minF) * 60; 1316 1317 getRational(&coord[0], (int)degF, 1); 1318 getRational(&coord[1], (int)minF, 1); 1319 getRational(&coord[2], (int)(secF * 10000), 10000); 1320 return NO_ERROR; 1321} 1322 1323/*=========================================================================== 1324 * FUNCTION : getExifDateTime 1325 * 1326 * DESCRIPTION: query exif date time 1327 * 1328 * PARAMETERS : 1329 * @dateTime : string to store exif date time 1330 * @count : lenght of the dateTime string 1331 * 1332 * RETURN : int32_t type of status 1333 * NO_ERROR -- success 1334 * none-zero failure code 1335 *==========================================================================*/ 1336int32_t getExifDateTime(char *dateTime, uint32_t &count) 1337{ 1338 //get time and date from system 1339 time_t rawtime; 1340 struct tm * timeinfo; 1341 time(&rawtime); 1342 timeinfo = localtime (&rawtime); 1343 //Write datetime according to EXIF Spec 1344 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1345 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1346 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1347 timeinfo->tm_mday, timeinfo->tm_hour, 1348 timeinfo->tm_min, timeinfo->tm_sec); 1349 count = 20; 1350 1351 return NO_ERROR; 1352} 1353 1354/*=========================================================================== 1355 * FUNCTION : getExifFocalLength 1356 * 1357 * DESCRIPTION: get exif focal lenght 1358 * 1359 * PARAMETERS : 1360 * @focalLength : ptr to rational strcut to store focal lenght 1361 * 1362 * RETURN : int32_t type of status 1363 * NO_ERROR -- success 1364 * none-zero failure code 1365 *==========================================================================*/ 1366int32_t getExifFocalLength(rat_t *focalLength, float value) 1367{ 1368 int focalLengthValue = 1369 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1370 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1371} 1372 1373/*=========================================================================== 1374 * FUNCTION : getExifExpTimeInfo 1375 * 1376 * DESCRIPTION: get exif exposure time information 1377 * 1378 * PARAMETERS : 1379 * @expoTimeInfo : expousure time value 1380 * RETURN : nt32_t type of status 1381 * NO_ERROR -- success 1382 * none-zero failure code 1383 *==========================================================================*/ 1384int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value) 1385{ 1386 1387 int cal_exposureTime; 1388 if (value != 0) 1389 cal_exposureTime = value; 1390 else 1391 cal_exposureTime = 60; 1392 1393 return getRational(expoTimeInfo, 1, cal_exposureTime); 1394} 1395 1396/*=========================================================================== 1397 * FUNCTION : getExifGpsProcessingMethod 1398 * 1399 * DESCRIPTION: get GPS processing method 1400 * 1401 * PARAMETERS : 1402 * @gpsProcessingMethod : string to store GPS process method 1403 * @count : lenght of the string 1404 * 1405 * RETURN : int32_t type of status 1406 * NO_ERROR -- success 1407 * none-zero failure code 1408 *==========================================================================*/ 1409int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1410 uint32_t &count, char* value) 1411{ 1412 if(value != NULL) { 1413 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1414 count = EXIF_ASCII_PREFIX_SIZE; 1415 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1416 count += strlen(value); 1417 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1418 return NO_ERROR; 1419 } else { 1420 return BAD_VALUE; 1421 } 1422} 1423 1424/*=========================================================================== 1425 * FUNCTION : getExifLatitude 1426 * 1427 * DESCRIPTION: get exif latitude 1428 * 1429 * PARAMETERS : 1430 * @latitude : ptr to rational struct to store latitude info 1431 * @ladRef : charater to indicate latitude reference 1432 * 1433 * RETURN : int32_t type of status 1434 * NO_ERROR -- success 1435 * none-zero failure code 1436 *==========================================================================*/ 1437int32_t getExifLatitude(rat_t *latitude, 1438 char *latRef, double value) 1439{ 1440 char str[30]; 1441 snprintf(str, sizeof(str), "%f", value); 1442 if(str != NULL) { 1443 parseGPSCoordinate(str, latitude); 1444 1445 //set Latitude Ref 1446 float latitudeValue = strtof(str, 0); 1447 if(latitudeValue < 0.0f) { 1448 latRef[0] = 'S'; 1449 } else { 1450 latRef[0] = 'N'; 1451 } 1452 latRef[1] = '\0'; 1453 return NO_ERROR; 1454 }else{ 1455 return BAD_VALUE; 1456 } 1457} 1458 1459/*=========================================================================== 1460 * FUNCTION : getExifLongitude 1461 * 1462 * DESCRIPTION: get exif longitude 1463 * 1464 * PARAMETERS : 1465 * @longitude : ptr to rational struct to store longitude info 1466 * @lonRef : charater to indicate longitude reference 1467 * 1468 * RETURN : int32_t type of status 1469 * NO_ERROR -- success 1470 * none-zero failure code 1471 *==========================================================================*/ 1472int32_t getExifLongitude(rat_t *longitude, 1473 char *lonRef, double value) 1474{ 1475 char str[30]; 1476 snprintf(str, sizeof(str), "%f", value); 1477 if(str != NULL) { 1478 parseGPSCoordinate(str, longitude); 1479 1480 //set Longitude Ref 1481 float longitudeValue = strtof(str, 0); 1482 if(longitudeValue < 0.0f) { 1483 lonRef[0] = 'W'; 1484 } else { 1485 lonRef[0] = 'E'; 1486 } 1487 lonRef[1] = '\0'; 1488 return NO_ERROR; 1489 }else{ 1490 return BAD_VALUE; 1491 } 1492} 1493 1494/*=========================================================================== 1495 * FUNCTION : getExifAltitude 1496 * 1497 * DESCRIPTION: get exif altitude 1498 * 1499 * PARAMETERS : 1500 * @altitude : ptr to rational struct to store altitude info 1501 * @altRef : charater to indicate altitude reference 1502 * 1503 * RETURN : int32_t type of status 1504 * NO_ERROR -- success 1505 * none-zero failure code 1506 *==========================================================================*/ 1507int32_t getExifAltitude(rat_t *altitude, 1508 char *altRef, double value) 1509{ 1510 char str[30]; 1511 snprintf(str, sizeof(str), "%f", value); 1512 if(str != NULL) { 1513 double value = atof(str); 1514 *altRef = 0; 1515 if(value < 0){ 1516 *altRef = 1; 1517 value = -value; 1518 } 1519 return getRational(altitude, value*1000, 1000); 1520 }else{ 1521 return BAD_VALUE; 1522 } 1523} 1524 1525/*=========================================================================== 1526 * FUNCTION : getExifGpsDateTimeStamp 1527 * 1528 * DESCRIPTION: get exif GPS date time stamp 1529 * 1530 * PARAMETERS : 1531 * @gpsDateStamp : GPS date time stamp string 1532 * @bufLen : length of the string 1533 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1534 * 1535 * RETURN : int32_t type of status 1536 * NO_ERROR -- success 1537 * none-zero failure code 1538 *==========================================================================*/ 1539int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1540 uint32_t bufLen, 1541 rat_t *gpsTimeStamp, int64_t value) 1542{ 1543 char str[30]; 1544 snprintf(str, sizeof(str), "%lld", value); 1545 if(str != NULL) { 1546 time_t unixTime = (time_t)atol(str); 1547 struct tm *UTCTimestamp = gmtime(&unixTime); 1548 1549 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1550 1551 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1552 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1553 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1554 1555 return NO_ERROR; 1556 } else { 1557 return BAD_VALUE; 1558 } 1559} 1560 1561int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1562 cam_rational_type_t step) 1563{ 1564 exposure_val->num = exposure_comp * step.numerator; 1565 exposure_val->denom = step.denominator; 1566 return 0; 1567} 1568/*=========================================================================== 1569 * FUNCTION : getExifData 1570 * 1571 * DESCRIPTION: get exif data to be passed into jpeg encoding 1572 * 1573 * PARAMETERS : none 1574 * 1575 * RETURN : exif data from user setting and GPS 1576 *==========================================================================*/ 1577QCamera3Exif *QCamera3PicChannel::getExifData() 1578{ 1579 QCamera3Exif *exif = new QCamera3Exif(); 1580 if (exif == NULL) { 1581 ALOGE("%s: No memory for QCamera3Exif", __func__); 1582 return NULL; 1583 } 1584 1585 int32_t rc = NO_ERROR; 1586 uint32_t count = 0; 1587 1588 // add exif entries 1589 char dateTime[20]; 1590 memset(dateTime, 0, sizeof(dateTime)); 1591 count = 20; 1592 rc = getExifDateTime(dateTime, count); 1593 if(rc == NO_ERROR) { 1594 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1595 EXIF_ASCII, 1596 count, 1597 (void *)dateTime); 1598 } else { 1599 ALOGE("%s: getExifDateTime failed", __func__); 1600 } 1601 1602 rat_t focalLength; 1603 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1604 if (rc == NO_ERROR) { 1605 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1606 EXIF_RATIONAL, 1607 1, 1608 (void *)&(focalLength)); 1609 } else { 1610 ALOGE("%s: getExifFocalLength failed", __func__); 1611 } 1612 1613 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity; 1614 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1615 EXIF_SHORT, 1616 1, 1617 (void *)&(isoSpeed)); 1618 1619 rat_t sensorExpTime ; 1620 rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time); 1621 if (rc == NO_ERROR){ 1622 exif->addEntry(EXIFTAGID_EXPOSURE_TIME, 1623 EXIF_RATIONAL, 1624 1, 1625 (void *)&(sensorExpTime)); 1626 } else { 1627 ALOGE("now addEntry for EXIFTAGID_EXPOSURE_TIME is %d", sensorExpTime); 1628 } 1629 1630 if (strlen(mJpegSettings->gps_processing_method) > 0) { 1631 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1632 count = 0; 1633 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1634 if(rc == NO_ERROR) { 1635 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1636 EXIF_ASCII, 1637 count, 1638 (void *)gpsProcessingMethod); 1639 } else { 1640 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1641 } 1642 } 1643 1644 if (mJpegSettings->gps_coordinates[0]) { 1645 rat_t latitude[3]; 1646 char latRef[2]; 1647 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0])); 1648 if(rc == NO_ERROR) { 1649 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1650 EXIF_RATIONAL, 1651 3, 1652 (void *)latitude); 1653 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1654 EXIF_ASCII, 1655 2, 1656 (void *)latRef); 1657 } else { 1658 ALOGE("%s: getExifLatitude failed", __func__); 1659 } 1660 } 1661 1662 if (mJpegSettings->gps_coordinates[1]) { 1663 rat_t longitude[3]; 1664 char lonRef[2]; 1665 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1])); 1666 if(rc == NO_ERROR) { 1667 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1668 EXIF_RATIONAL, 1669 3, 1670 (void *)longitude); 1671 1672 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1673 EXIF_ASCII, 1674 2, 1675 (void *)lonRef); 1676 } else { 1677 ALOGE("%s: getExifLongitude failed", __func__); 1678 } 1679 } 1680 1681 if (mJpegSettings->gps_coordinates[2]) { 1682 rat_t altitude; 1683 char altRef; 1684 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2])); 1685 if(rc == NO_ERROR) { 1686 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1687 EXIF_RATIONAL, 1688 1, 1689 (void *)&(altitude)); 1690 1691 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1692 EXIF_BYTE, 1693 1, 1694 (void *)&altRef); 1695 } else { 1696 ALOGE("%s: getExifAltitude failed", __func__); 1697 } 1698 } 1699 1700 if (mJpegSettings->gps_timestamp) { 1701 char gpsDateStamp[20]; 1702 rat_t gpsTimeStamp[3]; 1703 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp)); 1704 if(rc == NO_ERROR) { 1705 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1706 EXIF_ASCII, 1707 strlen(gpsDateStamp) + 1, 1708 (void *)gpsDateStamp); 1709 1710 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1711 EXIF_RATIONAL, 1712 3, 1713 (void *)gpsTimeStamp); 1714 } else { 1715 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1716 } 1717 } 1718 1719 srat_t exposure_val; 1720 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation, 1721 mJpegSettings->exposure_comp_step); 1722 if(rc == NO_ERROR) { 1723 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1724 EXIF_SRATIONAL, 1725 1, 1726 (void *)(&exposure_val)); 1727 } else { 1728 ALOGE("%s: getExifExposureValue failed ", __func__); 1729 } 1730 1731 return exif; 1732} 1733 1734int QCamera3PicChannel::kMaxBuffers = 1; 1735 1736/*=========================================================================== 1737 * FUNCTION : QCamera3ReprocessChannel 1738 * 1739 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1740 * 1741 * PARAMETERS : 1742 * @cam_handle : camera handle 1743 * @cam_ops : ptr to camera ops table 1744 * @pp_mask : post-proccess feature mask 1745 * 1746 * RETURN : none 1747 *==========================================================================*/ 1748QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle, 1749 mm_camera_ops_t *cam_ops, 1750 channel_cb_routine cb_routine, 1751 cam_padding_info_t *paddingInfo, 1752 void *userData, void *ch_hdl) : 1753 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData), 1754 picChHandle(ch_hdl), 1755 m_pSrcChannel(NULL), 1756 m_pMetaChannel(NULL), 1757 m_metaFrame(NULL), 1758 mMemory(NULL) 1759{ 1760 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 1761} 1762 1763 1764/*=========================================================================== 1765 * FUNCTION : QCamera3ReprocessChannel 1766 * 1767 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1768 * 1769 * PARAMETERS : 1770 * @cam_handle : camera handle 1771 * @cam_ops : ptr to camera ops table 1772 * @pp_mask : post-proccess feature mask 1773 * 1774 * RETURN : none 1775 *==========================================================================*/ 1776int32_t QCamera3ReprocessChannel::initialize() 1777{ 1778 int32_t rc = NO_ERROR; 1779 mm_camera_channel_attr_t attr; 1780 1781 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 1782 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 1783 attr.max_unmatched_frames = 1; 1784 1785 rc = init(&attr, NULL); 1786 if (rc < 0) { 1787 ALOGE("%s: init failed", __func__); 1788 } 1789 return rc; 1790} 1791 1792 1793/*=========================================================================== 1794 * FUNCTION : QCamera3ReprocessChannel 1795 * 1796 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1797 * 1798 * PARAMETERS : 1799 * @cam_handle : camera handle 1800 * @cam_ops : ptr to camera ops table 1801 * @pp_mask : post-proccess feature mask 1802 * 1803 * RETURN : none 1804 *==========================================================================*/ 1805void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1806 QCamera3Stream *stream) 1807{ 1808 //Got the pproc data callback. Now send to jpeg encoding 1809 uint8_t frameIndex; 1810 mm_camera_super_buf_t* frame = NULL; 1811 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle; 1812 1813 if(!super_frame) { 1814 ALOGE("%s: Invalid Super buffer",__func__); 1815 return; 1816 } 1817 1818 if(super_frame->num_bufs != 1) { 1819 ALOGE("%s: Multiple streams are not supported",__func__); 1820 return; 1821 } 1822 if(super_frame->bufs[0] == NULL ) { 1823 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1824 __func__); 1825 return; 1826 } 1827 1828 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1829 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1830 if (frame == NULL) { 1831 ALOGE("%s: Error allocating memory to save received_frame structure.", 1832 __func__); 1833 if(stream) { 1834 stream->bufDone(frameIndex); 1835 } 1836 return; 1837 } 1838 *frame = *super_frame; 1839 //queue back the metadata buffer 1840 if (m_metaFrame != NULL) { 1841 ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(m_metaFrame); 1842 free(m_metaFrame); 1843 m_metaFrame = NULL; 1844 } else { 1845 ALOGE("%s: Meta frame was NULL", __func__); 1846 } 1847 obj->m_postprocessor.processPPData(frame); 1848 return; 1849} 1850 1851/*=========================================================================== 1852 * FUNCTION : QCamera3ReprocessChannel 1853 * 1854 * DESCRIPTION: default constructor of QCamera3ReprocessChannel 1855 * 1856 * PARAMETERS : none 1857 * 1858 * RETURN : none 1859 *==========================================================================*/ 1860QCamera3ReprocessChannel::QCamera3ReprocessChannel() : 1861 m_pSrcChannel(NULL), 1862 m_pMetaChannel(NULL), 1863 m_metaFrame(NULL) 1864{ 1865} 1866 1867/*=========================================================================== 1868 * FUNCTION : QCamera3ReprocessChannel 1869 * 1870 * DESCRIPTION: register the buffers of the reprocess channel 1871 * 1872 * PARAMETERS : none 1873 * 1874 * RETURN : none 1875 *==========================================================================*/ 1876int32_t QCamera3ReprocessChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 1877{ 1878 return 0; 1879} 1880 1881/*=========================================================================== 1882 * FUNCTION : getStreamBufs 1883 * 1884 * DESCRIPTION: register the buffers of the reprocess channel 1885 * 1886 * PARAMETERS : none 1887 * 1888 * RETURN : QCamera3Memory * 1889 *==========================================================================*/ 1890QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len) 1891{ 1892 int rc = 0; 1893 1894 mMemory = new QCamera3HeapMemory(); 1895 if (!mMemory) { 1896 ALOGE("%s: unable to create reproc memory", __func__); 1897 return NULL; 1898 } 1899 1900 //Queue YUV buffers in the beginning mQueueAll = true 1901 rc = mMemory->allocate(2, len, true); 1902 if (rc < 0) { 1903 ALOGE("%s: unable to allocate reproc memory", __func__); 1904 delete mMemory; 1905 mMemory = NULL; 1906 return NULL; 1907 } 1908 return mMemory; 1909} 1910 1911/*=========================================================================== 1912 * FUNCTION : getStreamBufs 1913 * 1914 * DESCRIPTION: register the buffers of the reprocess channel 1915 * 1916 * PARAMETERS : none 1917 * 1918 * RETURN : 1919 *==========================================================================*/ 1920void QCamera3ReprocessChannel::putStreamBufs() 1921{ 1922 mMemory->deallocate(); 1923 delete mMemory; 1924 mMemory = NULL; 1925} 1926 1927/*=========================================================================== 1928 * FUNCTION : ~QCamera3ReprocessChannel 1929 * 1930 * DESCRIPTION: destructor of QCamera3ReprocessChannel 1931 * 1932 * PARAMETERS : none 1933 * 1934 * RETURN : none 1935 *==========================================================================*/ 1936QCamera3ReprocessChannel::~QCamera3ReprocessChannel() 1937{ 1938} 1939 1940/*=========================================================================== 1941 * FUNCTION : getStreamBySourceHandle 1942 * 1943 * DESCRIPTION: find reprocess stream by its source stream handle 1944 * 1945 * PARAMETERS : 1946 * @srcHandle : source stream handle 1947 * 1948 * RETURN : ptr to reprocess stream if found. NULL if not found 1949 *==========================================================================*/ 1950QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle) 1951{ 1952 QCamera3Stream *pStream = NULL; 1953 1954 for (int i = 0; i < m_numStreams; i++) { 1955 if (mSrcStreamHandles[i] == srcHandle) { 1956 pStream = mStreams[i]; 1957 break; 1958 } 1959 } 1960 return pStream; 1961} 1962 1963/*=========================================================================== 1964 * FUNCTION : doReprocess 1965 * 1966 * DESCRIPTION: request to do a reprocess on the frame 1967 * 1968 * PARAMETERS : 1969 * @frame : frame to be performed a reprocess 1970 * 1971 * RETURN : int32_t type of status 1972 * NO_ERROR -- success 1973 * none-zero failure code 1974 *==========================================================================*/ 1975int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 1976 mm_camera_super_buf_t *meta_frame) 1977{ 1978 int32_t rc = 0; 1979 if (m_numStreams < 1) { 1980 ALOGE("%s: No reprocess stream is created", __func__); 1981 return -1; 1982 } 1983 if (m_pSrcChannel == NULL) { 1984 ALOGE("%s: No source channel for reprocess", __func__); 1985 return -1; 1986 } 1987 m_metaFrame = meta_frame; 1988 for (int i = 0; i < frame->num_bufs; i++) { 1989 QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id); 1990 if (pStream != NULL) { 1991 cam_stream_parm_buffer_t param; 1992 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1993 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1994 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 1995 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 1996 if (meta_frame != NULL) { 1997 param.reprocess.meta_present = 1; 1998 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 1999 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2000 } 2001 rc = pStream->setParameter(param); 2002 if (rc != NO_ERROR) { 2003 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2004 break; 2005 } 2006 } 2007 } 2008 return rc; 2009} 2010 2011/*=========================================================================== 2012 * FUNCTION : doReprocess 2013 * 2014 * DESCRIPTION: request to do a reprocess on the frame 2015 * 2016 * PARAMETERS : 2017 * @buf_fd : fd to the input buffer that needs reprocess 2018 * @buf_lenght : length of the input buffer 2019 * @ret_val : result of reprocess. 2020 * Example: Could be faceID in case of register face image. 2021 * 2022 * RETURN : int32_t type of status 2023 * NO_ERROR -- success 2024 * none-zero failure code 2025 *==========================================================================*/ 2026int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd, 2027 uint32_t buf_length, 2028 int32_t &ret_val, 2029 mm_camera_super_buf_t *meta_frame) 2030{ 2031 int32_t rc = 0; 2032 if (m_numStreams < 1) { 2033 ALOGE("%s: No reprocess stream is created", __func__); 2034 return -1; 2035 } 2036 if (meta_frame == NULL) { 2037 ALOGE("%s: Did not get corresponding metadata in time", __func__); 2038 return -1; 2039 } 2040 2041 uint32_t buf_idx = 0; 2042 for (int i = 0; i < m_numStreams; i++) { 2043 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2044 buf_idx, -1, 2045 buf_fd, buf_length); 2046 2047 if (rc == NO_ERROR) { 2048 cam_stream_parm_buffer_t param; 2049 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2050 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2051 param.reprocess.buf_index = buf_idx; 2052 param.reprocess.meta_present = 1; 2053 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2054 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2055 rc = mStreams[i]->setParameter(param); 2056 if (rc == NO_ERROR) { 2057 ret_val = param.reprocess.ret_val; 2058 } 2059 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2060 buf_idx, -1); 2061 } 2062 } 2063 return rc; 2064} 2065 2066/*=========================================================================== 2067 * FUNCTION : addReprocStreamsFromSource 2068 * 2069 * DESCRIPTION: add reprocess streams from input source channel 2070 * 2071 * PARAMETERS : 2072 * @config : pp feature configuration 2073 * @pSrcChannel : ptr to input source channel that needs reprocess 2074 * @pMetaChannel : ptr to metadata channel to get corresp. metadata 2075 * 2076 * RETURN : int32_t type of status 2077 * NO_ERROR -- success 2078 * none-zero failure code 2079 *==========================================================================*/ 2080int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config, 2081 QCamera3Channel *pSrcChannel, 2082 QCamera3Channel *pMetaChannel) 2083{ 2084 int32_t rc = 0; 2085 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0); 2086 if (pSrcStream == NULL) { 2087 ALOGE("%s: source channel doesn't have a stream", __func__); 2088 return BAD_VALUE; 2089 } 2090 cam_stream_reproc_config_t reprocess_config; 2091 cam_dimension_t streamDim; 2092 cam_stream_type_t streamType; 2093 cam_format_t streamFormat; 2094 cam_frame_len_offset_t frameOffset; 2095 int num_buffers = 2; 2096 2097 streamType = CAM_STREAM_TYPE_OFFLINE_PROC; 2098 pSrcStream->getFormat(streamFormat); 2099 pSrcStream->getFrameDimension(streamDim); 2100 pSrcStream->getFrameOffset(frameOffset); 2101 2102 reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE; 2103 reprocess_config.online.input_stream_id = pSrcStream->getMyServerID(); 2104 reprocess_config.online.input_stream_type = pSrcStream->getMyType(); 2105 reprocess_config.pp_feature_config = config; 2106 2107 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle(); 2108 2109 if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 2110 if (reprocess_config.pp_feature_config.rotation == ROTATE_90 || 2111 reprocess_config.pp_feature_config.rotation == ROTATE_270) { 2112 // rotated by 90 or 270, need to switch width and height 2113 int32_t temp = streamDim.height; 2114 streamDim.height = streamDim.width; 2115 streamDim.width = temp; 2116 } 2117 } 2118 2119 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 2120 m_handle, 2121 m_camOps, 2122 mPaddingInfo, 2123 (QCamera3Channel*)this); 2124 if (pStream == NULL) { 2125 ALOGE("%s: No mem for Stream", __func__); 2126 return NO_MEMORY; 2127 } 2128 2129 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config, 2130 num_buffers,QCamera3Channel::streamCbRoutine, this); 2131 2132 2133 if (rc == 0) { 2134 mStreams[m_numStreams] = pStream; 2135 m_numStreams++; 2136 } else { 2137 ALOGE("%s: failed to create reprocess stream", __func__); 2138 delete pStream; 2139 } 2140 2141 if (rc == NO_ERROR) { 2142 m_pSrcChannel = pSrcChannel; 2143 m_pMetaChannel = pMetaChannel; 2144 } 2145 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 2146 ALOGE("%s: Request for super buffer failed",__func__); 2147 } 2148 return rc; 2149} 2150 2151 2152}; // namespace qcamera 2153