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