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