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