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