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