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