QCamera3Channel.cpp revision 2f0dc524b1cce88a85757118419d1dc08916e650
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 7 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 : getStreamByHandle 324 * 325 * DESCRIPTION: return stream object by stream handle 326 * 327 * PARAMETERS : 328 * @streamHandle : stream handle 329 * 330 * RETURN : stream object. NULL if not found 331 *==========================================================================*/ 332QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle) 333{ 334 for (int i = 0; i < m_numStreams; i++) { 335 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 336 return mStreams[i]; 337 } 338 } 339 return NULL; 340} 341 342/*=========================================================================== 343 * FUNCTION : getStreamByHandle 344 * 345 * DESCRIPTION: return stream object by stream handle 346 * 347 * PARAMETERS : 348 * @streamHandle : stream handle 349 * 350 * RETURN : stream object. NULL if not found 351 *==========================================================================*/ 352QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index) 353{ 354 if (index < m_numStreams) { 355 return mStreams[index]; 356 } 357 return NULL; 358} 359 360/*=========================================================================== 361 * FUNCTION : streamCbRoutine 362 * 363 * DESCRIPTION: callback routine for stream 364 * 365 * PARAMETERS : 366 * @streamHandle : stream handle 367 * 368 * RETURN : stream object. NULL if not found 369 *==========================================================================*/ 370void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 371 QCamera3Stream *stream, void *userdata) 372{ 373 QCamera3Channel *channel = (QCamera3Channel *)userdata; 374 if (channel == NULL) { 375 ALOGE("%s: invalid channel pointer", __func__); 376 return; 377 } 378 channel->streamCbRoutine(super_frame, stream); 379} 380 381/*=========================================================================== 382 * FUNCTION : QCamera3RegularChannel 383 * 384 * DESCRIPTION: constrcutor of QCamera3RegularChannel 385 * 386 * PARAMETERS : 387 * @cam_handle : camera handle 388 * @cam_ops : ptr to camera ops table 389 * @cb_routine : callback routine to frame aggregator 390 * @stream : camera3_stream_t structure 391 * 392 * RETURN : none 393 *==========================================================================*/ 394QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 395 mm_camera_ops_t *cam_ops, 396 channel_cb_routine cb_routine, 397 cam_padding_info_t *paddingInfo, 398 void *userData, 399 camera3_stream_t *stream) : 400 QCamera3Channel(cam_handle, cam_ops, cb_routine, 401 paddingInfo, userData), 402 mCamera3Stream(stream), 403 mNumBufs(0), 404 mCamera3Buffers(NULL), 405 mMemory(NULL) 406{ 407} 408 409/*=========================================================================== 410 * FUNCTION : ~QCamera3RegularChannel 411 * 412 * DESCRIPTION: destructor of QCamera3RegularChannel 413 * 414 * PARAMETERS : none 415 * 416 * RETURN : none 417 *==========================================================================*/ 418QCamera3RegularChannel::~QCamera3RegularChannel() 419{ 420 if (mCamera3Buffers) { 421 delete[] mCamera3Buffers; 422 } 423} 424 425int32_t QCamera3RegularChannel::initialize() 426{ 427 //TO DO 428 return 0; 429} 430 431/*=========================================================================== 432 * FUNCTION : request 433 * 434 * DESCRIPTION: process a request from camera service. Stream on if ncessary. 435 * 436 * PARAMETERS : 437 * @buffer : buffer to be filled for this request 438 * 439 * RETURN : 0 on a success start of capture 440 * -EINVAL on invalid input 441 * -ENODEV on serious error 442 *==========================================================================*/ 443int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber) 444{ 445 //FIX ME: Return buffer back in case of failures below. 446 447 int32_t rc = NO_ERROR; 448 int index; 449 if(!m_bIsActive) { 450 ALOGD("%s: First request on this channel starting stream",__func__); 451 start(); 452 if(rc != NO_ERROR) { 453 ALOGE("%s: Failed to start the stream on the request",__func__); 454 return rc; 455 } 456 } else { 457 ALOGV("%s: Request on an existing stream",__func__); 458 } 459 460 if(!mMemory) { 461 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 462 return NO_MEMORY; 463 } 464 465 index = mMemory->getMatchBufIndex((void*)buffer); 466 if(index < 0) { 467 ALOGE("%s: Could not find object among registered buffers",__func__); 468 return DEAD_OBJECT; 469 } 470 471 rc = mStreams[0]->bufDone(index); 472 if(rc != NO_ERROR) { 473 ALOGE("%s: Failed to Q new buffer to stream",__func__); 474 return rc; 475 } 476 477 rc = mMemory->markFrameNumber(index, frameNumber); 478 return rc; 479} 480 481/*=========================================================================== 482 * FUNCTION : registerBuffers 483 * 484 * DESCRIPTION: register streaming buffers to the channel object 485 * 486 * PARAMETERS : 487 * @num_buffers : number of buffers to be registered 488 * @buffers : buffer to be registered 489 * 490 * RETURN : 0 on a success start of capture 491 * -EINVAL on invalid input 492 * -ENOMEM on failure to register the buffer 493 * -ENODEV on serious error 494 *==========================================================================*/ 495int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 496{ 497 int rc = 0; 498 struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]); 499 cam_stream_type_t streamType; 500 cam_format_t streamFormat; 501 cam_dimension_t streamDim; 502 503 rc = init(NULL, NULL); 504 if (rc < 0) { 505 ALOGE("%s: init failed", __func__); 506 return rc; 507 } 508 509 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 510 if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) { 511 streamType = CAM_STREAM_TYPE_VIDEO; 512 streamFormat = CAM_FORMAT_YUV_420_NV12; 513 } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) { 514 streamType = CAM_STREAM_TYPE_PREVIEW; 515 streamFormat = CAM_FORMAT_YUV_420_NV21; 516 } else { 517 ALOGE("%s: priv_handle->flags 0x%x not supported", 518 __func__, priv_handle->flags); 519 return -EINVAL; 520 } 521 } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 522 streamType = CAM_STREAM_TYPE_PREVIEW; 523 streamFormat = CAM_FORMAT_YUV_420_NV21; 524 } else { 525 //TODO: Fail for other types of streams for now 526 ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__); 527 return -EINVAL; 528 } 529 530 /* Bookkeep buffer set because they go out of scope after register call */ 531 mNumBufs = num_buffers; 532 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 533 if (mCamera3Buffers == NULL) { 534 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 535 return -ENOMEM; 536 } 537 for (size_t i = 0; i < num_buffers; i++) 538 mCamera3Buffers[i] = buffers[i]; 539 540 streamDim.width = mCamera3Stream->width; 541 streamDim.height = mCamera3Stream->height; 542 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 543 num_buffers); 544 return rc; 545} 546 547void QCamera3RegularChannel::streamCbRoutine( 548 mm_camera_super_buf_t *super_frame, 549 QCamera3Stream *stream) 550{ 551 //FIXME Q Buf back in case of error? 552 uint8_t frameIndex; 553 buffer_handle_t *resultBuffer; 554 int32_t resultFrameNumber; 555 camera3_stream_buffer_t result; 556 557 if(!super_frame) { 558 ALOGE("%s: Invalid Super buffer",__func__); 559 return; 560 } 561 562 if(super_frame->num_bufs != 1) { 563 ALOGE("%s: Multiple streams are not supported",__func__); 564 return; 565 } 566 if(super_frame->bufs[0] == NULL ) { 567 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 568 __func__); 569 return; 570 } 571 572 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 573 if(frameIndex >= mNumBufs) { 574 ALOGE("%s: Error, Invalid index for buffer",__func__); 575 if(stream) { 576 stream->bufDone(frameIndex); 577 } 578 return; 579 } 580 581 ////Use below data to issue framework callback 582 resultBuffer = mCamera3Buffers[frameIndex]; 583 resultFrameNumber = mMemory->getFrameNumber(frameIndex); 584 585 result.stream = mCamera3Stream; 586 result.buffer = resultBuffer; 587 result.status = CAMERA3_BUFFER_STATUS_OK; 588 result.acquire_fence = -1; 589 result.release_fence = -1; 590 591 mChannelCB(NULL, &result, resultFrameNumber, mUserData); 592 return; 593} 594 595QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/) 596{ 597 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 598 ALOGE("%s: buffers not registered yet", __func__); 599 return NULL; 600 } 601 602 mMemory = new QCamera3GrallocMemory(); 603 if (mMemory == NULL) { 604 return NULL; 605 } 606 607 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 608 delete mMemory; 609 mMemory = NULL; 610 return NULL; 611 } 612 return mMemory; 613} 614 615void QCamera3RegularChannel::putStreamBufs() 616{ 617 mMemory->unregisterBuffers(); 618 delete mMemory; 619 mMemory = NULL; 620} 621 622int QCamera3RegularChannel::kMaxBuffers = 7; 623 624QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle, 625 mm_camera_ops_t *cam_ops, 626 channel_cb_routine cb_routine, 627 cam_padding_info_t *paddingInfo, 628 void *userData) : 629 QCamera3Channel(cam_handle, cam_ops, 630 cb_routine, paddingInfo, userData), 631 mMemory(NULL) 632{ 633} 634 635QCamera3MetadataChannel::~QCamera3MetadataChannel() 636{ 637 if (m_bIsActive) 638 stop(); 639 640 if (mMemory) { 641 mMemory->deallocate(); 642 delete mMemory; 643 mMemory = NULL; 644 } 645} 646 647int32_t QCamera3MetadataChannel::initialize() 648{ 649 int32_t rc; 650 cam_dimension_t streamDim; 651 652 if (mMemory || m_numStreams > 0) { 653 ALOGE("%s: metadata channel already initialized", __func__); 654 return -EINVAL; 655 } 656 657 rc = init(NULL, NULL); 658 if (rc < 0) { 659 ALOGE("%s: init failed", __func__); 660 return rc; 661 } 662 663 streamDim.width = sizeof(metadata_buffer_t), 664 streamDim.height = 1; 665 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX, 666 streamDim, MIN_STREAMING_BUFFER_NUM); 667 if (rc < 0) { 668 ALOGE("%s: addStream failed", __func__); 669 } 670 return rc; 671} 672 673int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/, 674 uint32_t frameNumber) 675{ 676 if (!m_bIsActive) { 677 return start(); 678 } 679 else 680 return 0; 681} 682 683int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/, 684 buffer_handle_t ** /*buffers*/) 685{ 686 // no registerBuffers are supported for metadata channel 687 return -EINVAL; 688} 689 690void QCamera3MetadataChannel::streamCbRoutine( 691 mm_camera_super_buf_t *super_frame, 692 QCamera3Stream *stream) 693{ 694 uint32_t requestNumber = 0; 695 if (super_frame == NULL || super_frame->num_bufs != 1) { 696 ALOGE("%s: super_frame is not valid", __func__); 697 return; 698 } 699 mChannelCB(super_frame, NULL, requestNumber, mUserData); 700 701 //Return the buffer 702 stream->bufDone(super_frame->bufs[0]->buf_idx); 703} 704 705QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len) 706{ 707 int rc; 708 if (len < sizeof(metadata_buffer_t)) { 709 ALOGE("%s: size doesn't match %d vs %d", __func__, 710 len, sizeof(metadata_buffer_t)); 711 return NULL; 712 } 713 mMemory = new QCamera3HeapMemory(); 714 if (!mMemory) { 715 ALOGE("%s: unable to create metadata memory", __func__); 716 return NULL; 717 } 718 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true); 719 if (rc < 0) { 720 ALOGE("%s: unable to allocate metadata memory", __func__); 721 delete mMemory; 722 mMemory = NULL; 723 return NULL; 724 } 725 memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t)); 726 return mMemory; 727} 728 729void QCamera3MetadataChannel::putStreamBufs() 730{ 731 mMemory->deallocate(); 732 delete mMemory; 733 mMemory = NULL; 734} 735 736/*=========================================================================== 737 * FUNCTION : jpegEvtHandle 738 * 739 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events. 740 Construct result payload and call mChannelCb to deliver buffer 741 to framework. 742 * 743 * PARAMETERS : 744 * @status : status of jpeg job 745 * @client_hdl: jpeg client handle 746 * @jobId : jpeg job Id 747 * @p_ouput : ptr to jpeg output result struct 748 * @userdata : user data ptr 749 * 750 * RETURN : none 751 *==========================================================================*/ 752void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status, 753 uint32_t /*client_hdl*/, 754 uint32_t jobId, 755 mm_jpeg_output_t *p_output, 756 void *userdata) 757{ 758 buffer_handle_t *resultBuffer; 759 int32_t resultFrameNumber; 760 int resultStatus = CAMERA3_BUFFER_STATUS_OK; 761 camera3_stream_buffer_t result; 762 camera3_jpeg_blob_t jpegHeader; 763 char* jpeg_eof = 0; 764 int maxJpegSize; 765 QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata; 766 if (obj) { 767 //Construct payload for process_capture_result. Call mChannelCb 768 769 qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId); 770 771 if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) { 772 ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status); 773 resultStatus = CAMERA3_BUFFER_STATUS_ERROR; 774 } 775 776 //Construct jpeg transient header of type camera3_jpeg_blob_t 777 //Append at the end of jpeg image of buf_filled_len size 778 779 jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID; 780 jpegHeader.jpeg_size = p_output->buf_filled_len; 781 782 783 char* jpeg_buf = (char *)p_output->buf_vaddr; 784 785 if(obj->mJpegSettings->max_jpeg_size <= 0 || 786 obj->mJpegSettings->max_jpeg_size > obj->mMemory->getSize(obj->mCurrentBufIndex)){ 787 ALOGE("%s:Max Jpeg size :%d is out of valid range setting to size of buffer", 788 __func__, obj->mJpegSettings->max_jpeg_size); 789 maxJpegSize = obj->mMemory->getSize(obj->mCurrentBufIndex); 790 } else { 791 maxJpegSize = obj->mJpegSettings->max_jpeg_size; 792 ALOGE("%s: Setting max jpeg size to %d",__func__, maxJpegSize); 793 } 794 jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)]; 795 memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader)); 796 obj->mMemory->cleanInvalidateCache(obj->mCurrentBufIndex); 797 798 ////Use below data to issue framework callback 799 resultBuffer = obj->mCamera3Buffers[obj->mCurrentBufIndex]; 800 resultFrameNumber = obj->mMemory->getFrameNumber(obj->mCurrentBufIndex); 801 802 result.stream = obj->mCamera3Stream; 803 result.buffer = resultBuffer; 804 result.status = resultStatus; 805 result.acquire_fence = -1; 806 result.release_fence = -1; 807 808 ALOGD("%s: Issue Callback", __func__); 809 obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData); 810 811 // release internal data for jpeg job 812 if (job != NULL) { 813 obj->m_postprocessor.releaseJpegJobData(job); 814 free(job); 815 } 816 return; 817 // } 818 } else { 819 ALOGE("%s: Null userdata in jpeg callback", __func__); 820 } 821} 822 823QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle, 824 mm_camera_ops_t *cam_ops, 825 channel_cb_routine cb_routine, 826 cam_padding_info_t *paddingInfo, 827 void *userData, 828 camera3_stream_t *stream) : 829 QCamera3Channel(cam_handle, cam_ops, cb_routine, 830 paddingInfo, userData), 831 mCamera3Stream(stream), 832 mNumBufs(0), 833 mCamera3Buffers(NULL), 834 mJpegSettings(NULL), 835 mCurrentBufIndex(-1), 836 mMemory(NULL), 837 mYuvMemory(NULL), 838 m_postprocessor(this) 839{ 840 int32_t rc = m_postprocessor.init(jpegEvtHandle, this); 841 if (rc != 0) { 842 ALOGE("Init Postprocessor failed"); 843 } 844} 845 846QCamera3PicChannel::~QCamera3PicChannel() 847{ 848 int32_t rc = m_postprocessor.deinit(); 849 if (rc != 0) { 850 ALOGE("De-init Postprocessor failed"); 851 } 852 if (mCamera3Buffers) { 853 delete[] mCamera3Buffers; 854 } 855} 856 857int32_t QCamera3PicChannel::initialize() 858{ 859 int32_t rc = NO_ERROR; 860 cam_dimension_t streamDim; 861 cam_stream_type_t streamType; 862 cam_format_t streamFormat; 863 mm_camera_channel_attr_t attr; 864 865 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 866 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 867 attr.look_back = 1; 868 attr.post_frame_skip = 1; 869 attr.water_mark = 1; 870 attr.max_unmatched_frames = 1; 871 872 rc = init(&attr, QCamera3PicChannel::dataNotifyCB); 873 if (rc < 0) { 874 ALOGE("%s: init failed", __func__); 875 return rc; 876 } 877 878 streamType = CAM_STREAM_TYPE_SNAPSHOT; 879 streamFormat = CAM_FORMAT_YUV_420_NV21; 880 streamDim.width = mCamera3Stream->width; 881 streamDim.height = mCamera3Stream->height; 882 883 int num_buffers = 1; 884 885 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 886 num_buffers); 887 888 889 return rc; 890} 891 892int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, uint32_t frameNumber, jpeg_settings_t* jpegSettings) 893{ 894 //FIX ME: Return buffer back in case of failures below. 895 896 int32_t rc = NO_ERROR; 897 int index; 898 mJpegSettings = jpegSettings; 899 900 if(!m_bIsActive) { 901 ALOGD("%s: First request on this channel starting stream",__func__); 902 //Stream on for main image. YUV buffer is queued to the kernel at the end of this call. 903 rc = start(); 904 } else { 905 mStreams[0]->bufDone(0); 906 ALOGD("%s: Request on an existing stream",__func__); 907 } 908 909 if(rc != NO_ERROR) { 910 ALOGE("%s: Failed to start the stream on the request",__func__); 911 return rc; 912 } 913 914 915 if(!mMemory) { 916 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 917 return NO_MEMORY; 918 } 919 920 index = mMemory->getMatchBufIndex((void*)buffer); 921 if(index < 0) { 922 ALOGE("%s: Could not find object among registered buffers",__func__); 923 return DEAD_OBJECT; 924 } 925 rc = mMemory->markFrameNumber(index, frameNumber); 926 927 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer 928 mCurrentBufIndex = index; 929 m_postprocessor.start(mMemory, index); 930 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 931 ALOGE("%s: Request for super buffer failed",__func__); 932 } 933 934 return rc; 935} 936 937/*=========================================================================== 938 * FUNCTION : dataNotifyCB 939 * 940 * DESCRIPTION: Channel Level callback used for super buffer data notify. 941 * This function is registered with mm-camera-interface to handle 942 * data notify 943 * 944 * PARAMETERS : 945 * @recvd_frame : stream frame received 946 * userdata : user data ptr 947 * 948 * RETURN : none 949 *==========================================================================*/ 950void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 951 void *userdata) 952{ 953 ALOGV("%s: E\n", __func__); 954 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 955 956 if (channel == NULL) { 957 ALOGE("%s: invalid channel pointer", __func__); 958 return; 959 } 960 961 if(channel->m_numStreams != 1) { 962 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 963 return; 964 } 965 966 967 if(channel->mStreams[0] == NULL) { 968 ALOGE("%s: Error: Invalid Stream object",__func__); 969 return; 970 } 971 972 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 973 974 ALOGV("%s: X\n", __func__); 975 return; 976} 977 978 979int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 980 buffer_handle_t **buffers) 981{ 982 int rc = 0; 983 cam_stream_type_t streamType; 984 cam_format_t streamFormat; 985 986 ALOGV("%s: E",__func__); 987 rc = QCamera3PicChannel::initialize(); 988 if (rc < 0) { 989 ALOGE("%s: init failed", __func__); 990 return rc; 991 } 992 993 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 994 streamType = CAM_STREAM_TYPE_SNAPSHOT; 995 streamFormat = CAM_FORMAT_YUV_420_NV21; 996 } else { 997 //TODO: Fail for other types of streams for now 998 ALOGE("%s: format is not BLOB", __func__); 999 return -EINVAL; 1000 } 1001 /* Bookkeep buffer set because they go out of scope after register call */ 1002 mNumBufs = num_buffers; 1003 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 1004 if (mCamera3Buffers == NULL) { 1005 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 1006 return -ENOMEM; 1007 } 1008 for (size_t i = 0; i < num_buffers; i++) 1009 mCamera3Buffers[i] = buffers[i]; 1010 1011 ALOGV("%s: X",__func__); 1012 return rc; 1013} 1014 1015void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1016 QCamera3Stream *stream) 1017{ 1018 //TODO 1019 //Used only for getting YUV. Jpeg callback will be sent back from channel 1020 //directly to HWI. Refer to func jpegEvtHandle 1021 1022 //Got the yuv callback. Calling yuv callback handler in PostProc 1023 uint8_t frameIndex; 1024 mm_camera_super_buf_t* frame = NULL; 1025 1026 if(!super_frame) { 1027 ALOGE("%s: Invalid Super buffer",__func__); 1028 return; 1029 } 1030 1031 if(super_frame->num_bufs != 1) { 1032 ALOGE("%s: Multiple streams are not supported",__func__); 1033 return; 1034 } 1035 if(super_frame->bufs[0] == NULL ) { 1036 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1037 __func__); 1038 return; 1039 } 1040 1041 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1042 if(frameIndex >= mNumBufs) { 1043 ALOGE("%s: Error, Invalid index for buffer",__func__); 1044 if(stream) { 1045 stream->bufDone(frameIndex); 1046 } 1047 return; 1048 } 1049 1050 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1051 if (frame == NULL) { 1052 ALOGE("%s: Error allocating memory to save received_frame structure.", 1053 __func__); 1054 if(stream) { 1055 stream->bufDone(frameIndex); 1056 } 1057 return; 1058 } 1059 *frame = *super_frame; 1060 1061 m_postprocessor.processData(frame); 1062 return; 1063} 1064 1065QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1066{ 1067 int rc = 0; 1068 1069 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1070 ALOGE("%s: buffers not registered yet", __func__); 1071 return NULL; 1072 } 1073 1074 mMemory = new QCamera3GrallocMemory(); 1075 if (mMemory == NULL) { 1076 return NULL; 1077 } 1078 1079 //Registering Jpeg output buffer 1080 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1081 delete mMemory; 1082 mMemory = NULL; 1083 return NULL; 1084 } 1085 1086 mYuvMemory = new QCamera3HeapMemory(); 1087 if (!mYuvMemory) { 1088 ALOGE("%s: unable to create metadata memory", __func__); 1089 return NULL; 1090 } 1091 1092 //Queue YUV buffers in the beginning mQueueAll = true 1093 rc = mYuvMemory->allocate(1, len, true); 1094 if (rc < 0) { 1095 ALOGE("%s: unable to allocate metadata memory", __func__); 1096 delete mYuvMemory; 1097 mYuvMemory = NULL; 1098 return NULL; 1099 } 1100 return mYuvMemory; 1101} 1102 1103void QCamera3PicChannel::putStreamBufs() 1104{ 1105 mMemory->unregisterBuffers(); 1106 delete mMemory; 1107 mMemory = NULL; 1108 1109 mYuvMemory->deallocate(); 1110 delete mYuvMemory; 1111 mYuvMemory = NULL; 1112} 1113 1114/*=========================================================================== 1115 * FUNCTION : needRotationReprocess 1116 * 1117 * DESCRIPTION: if online rotation needs to be done by cpp 1118 * 1119 * PARAMETERS : none 1120 * 1121 * RETURN : true: needed 1122 * false: no need 1123 *==========================================================================*/ 1124bool QCamera3PicChannel::needOnlineRotation() 1125{ 1126 //TODO: For B Family chips, we need to do something different 1127 // because JPEG encoder cannot do rotation. 1128 return false; 1129} 1130 1131/*=========================================================================== 1132 * FUNCTION : getThumbnailSize 1133 * 1134 * DESCRIPTION: get user set thumbnail size 1135 * 1136 * PARAMETERS : 1137 * @dim : output of thumbnail dimension 1138 * 1139 * RETURN : none 1140 *==========================================================================*/ 1141void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1142{ 1143 dim = mJpegSettings->thumbnail_size; 1144} 1145 1146/*=========================================================================== 1147 * FUNCTION : getJpegQuality 1148 * 1149 * DESCRIPTION: get user set jpeg quality 1150 * 1151 * PARAMETERS : none 1152 * 1153 * RETURN : jpeg quality setting 1154 *==========================================================================*/ 1155int QCamera3PicChannel::getJpegQuality() 1156{ 1157 int quality = mJpegSettings->jpeg_quality; 1158 if (quality < 0) { 1159 quality = 85; //set to default quality value 1160 } 1161 return quality; 1162} 1163 1164/*=========================================================================== 1165 * FUNCTION : getJpegRotation 1166 * 1167 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1168 * 1169 * PARAMETERS : none 1170 * 1171 * RETURN : rotation information 1172 *==========================================================================*/ 1173int QCamera3PicChannel::getJpegRotation() { 1174 int rotation = mJpegSettings->jpeg_orientation; 1175 if (rotation < 0) { 1176 rotation = 0; 1177 } 1178 return rotation; 1179} 1180 1181/*=========================================================================== 1182 * FUNCTION : getRational 1183 * 1184 * DESCRIPTION: compose rational struct 1185 * 1186 * PARAMETERS : 1187 * @rat : ptr to struct to store rational info 1188 * @num :num of the rational 1189 * @denom : denom of the rational 1190 * 1191 * RETURN : int32_t type of status 1192 * NO_ERROR -- success 1193 * none-zero failure code 1194 *==========================================================================*/ 1195int32_t getRational(rat_t *rat, int num, int denom) 1196{ 1197 if (NULL == rat) { 1198 ALOGE("%s: NULL rat input", __func__); 1199 return BAD_VALUE; 1200 } 1201 rat->num = num; 1202 rat->denom = denom; 1203 return NO_ERROR; 1204} 1205 1206/*=========================================================================== 1207 * FUNCTION : parseGPSCoordinate 1208 * 1209 * DESCRIPTION: parse GPS coordinate string 1210 * 1211 * PARAMETERS : 1212 * @coord_str : [input] coordinate string 1213 * @coord : [output] ptr to struct to store coordinate 1214 * 1215 * RETURN : int32_t type of status 1216 * NO_ERROR -- success 1217 * none-zero failure code 1218 *==========================================================================*/ 1219int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1220{ 1221 if(coord == NULL) { 1222 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1223 return BAD_VALUE; 1224 } 1225 float degF = atof(coord_str); 1226 if (degF < 0) { 1227 degF = -degF; 1228 } 1229 float minF = (degF - (int) degF) * 60; 1230 float secF = (minF - (int) minF) * 60; 1231 1232 getRational(&coord[0], (int)degF, 1); 1233 getRational(&coord[1], (int)minF, 1); 1234 getRational(&coord[2], (int)(secF * 10000), 10000); 1235 return NO_ERROR; 1236} 1237 1238/*=========================================================================== 1239 * FUNCTION : getExifDateTime 1240 * 1241 * DESCRIPTION: query exif date time 1242 * 1243 * PARAMETERS : 1244 * @dateTime : string to store exif date time 1245 * @count : lenght of the dateTime string 1246 * 1247 * RETURN : int32_t type of status 1248 * NO_ERROR -- success 1249 * none-zero failure code 1250 *==========================================================================*/ 1251int32_t getExifDateTime(char *dateTime, uint32_t &count) 1252{ 1253 //get time and date from system 1254 time_t rawtime; 1255 struct tm * timeinfo; 1256 time(&rawtime); 1257 timeinfo = localtime (&rawtime); 1258 //Write datetime according to EXIF Spec 1259 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1260 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1261 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1262 timeinfo->tm_mday, timeinfo->tm_hour, 1263 timeinfo->tm_min, timeinfo->tm_sec); 1264 count = 20; 1265 1266 return NO_ERROR; 1267} 1268 1269/*=========================================================================== 1270 * FUNCTION : getExifFocalLength 1271 * 1272 * DESCRIPTION: get exif focal lenght 1273 * 1274 * PARAMETERS : 1275 * @focalLength : ptr to rational strcut to store focal lenght 1276 * 1277 * RETURN : int32_t type of status 1278 * NO_ERROR -- success 1279 * none-zero failure code 1280 *==========================================================================*/ 1281int32_t getExifFocalLength(rat_t *focalLength, float value) 1282{ 1283 int focalLengthValue = 1284 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1285 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1286} 1287 1288/*=========================================================================== 1289 * FUNCTION : getExifGpsProcessingMethod 1290 * 1291 * DESCRIPTION: get GPS processing method 1292 * 1293 * PARAMETERS : 1294 * @gpsProcessingMethod : string to store GPS process method 1295 * @count : lenght of the string 1296 * 1297 * RETURN : int32_t type of status 1298 * NO_ERROR -- success 1299 * none-zero failure code 1300 *==========================================================================*/ 1301int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1302 uint32_t &count, char* value) 1303{ 1304 if(value != NULL) { 1305 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1306 count = EXIF_ASCII_PREFIX_SIZE; 1307 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1308 count += strlen(value); 1309 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1310 return NO_ERROR; 1311 } else { 1312 return BAD_VALUE; 1313 } 1314} 1315 1316/*=========================================================================== 1317 * FUNCTION : getExifLatitude 1318 * 1319 * DESCRIPTION: get exif latitude 1320 * 1321 * PARAMETERS : 1322 * @latitude : ptr to rational struct to store latitude info 1323 * @ladRef : charater to indicate latitude reference 1324 * 1325 * RETURN : int32_t type of status 1326 * NO_ERROR -- success 1327 * none-zero failure code 1328 *==========================================================================*/ 1329int32_t getExifLatitude(rat_t *latitude, 1330 char *latRef, double value) 1331{ 1332 char str[30]; 1333 snprintf(str, sizeof(str), "%f", value); 1334 if(str != NULL) { 1335 parseGPSCoordinate(str, latitude); 1336 1337 //set Latitude Ref 1338 float latitudeValue = strtof(str, 0); 1339 if(latitudeValue < 0.0f) { 1340 latRef[0] = 'S'; 1341 } else { 1342 latRef[0] = 'N'; 1343 } 1344 latRef[1] = '\0'; 1345 return NO_ERROR; 1346 }else{ 1347 return BAD_VALUE; 1348 } 1349} 1350 1351/*=========================================================================== 1352 * FUNCTION : getExifLongitude 1353 * 1354 * DESCRIPTION: get exif longitude 1355 * 1356 * PARAMETERS : 1357 * @longitude : ptr to rational struct to store longitude info 1358 * @lonRef : charater to indicate longitude reference 1359 * 1360 * RETURN : int32_t type of status 1361 * NO_ERROR -- success 1362 * none-zero failure code 1363 *==========================================================================*/ 1364int32_t getExifLongitude(rat_t *longitude, 1365 char *lonRef, double value) 1366{ 1367 char str[30]; 1368 snprintf(str, sizeof(str), "%f", value); 1369 if(str != NULL) { 1370 parseGPSCoordinate(str, longitude); 1371 1372 //set Longitude Ref 1373 float longitudeValue = strtof(str, 0); 1374 if(longitudeValue < 0.0f) { 1375 lonRef[0] = 'W'; 1376 } else { 1377 lonRef[0] = 'E'; 1378 } 1379 lonRef[1] = '\0'; 1380 return NO_ERROR; 1381 }else{ 1382 return BAD_VALUE; 1383 } 1384} 1385 1386/*=========================================================================== 1387 * FUNCTION : getExifAltitude 1388 * 1389 * DESCRIPTION: get exif altitude 1390 * 1391 * PARAMETERS : 1392 * @altitude : ptr to rational struct to store altitude info 1393 * @altRef : charater to indicate altitude reference 1394 * 1395 * RETURN : int32_t type of status 1396 * NO_ERROR -- success 1397 * none-zero failure code 1398 *==========================================================================*/ 1399int32_t getExifAltitude(rat_t *altitude, 1400 char *altRef, double value) 1401{ 1402 char str[30]; 1403 snprintf(str, sizeof(str), "%f", value); 1404 if(str != NULL) { 1405 double value = atof(str); 1406 *altRef = 0; 1407 if(value < 0){ 1408 *altRef = 1; 1409 value = -value; 1410 } 1411 return getRational(altitude, value*1000, 1000); 1412 }else{ 1413 return BAD_VALUE; 1414 } 1415} 1416 1417/*=========================================================================== 1418 * FUNCTION : getExifGpsDateTimeStamp 1419 * 1420 * DESCRIPTION: get exif GPS date time stamp 1421 * 1422 * PARAMETERS : 1423 * @gpsDateStamp : GPS date time stamp string 1424 * @bufLen : length of the string 1425 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1426 * 1427 * RETURN : int32_t type of status 1428 * NO_ERROR -- success 1429 * none-zero failure code 1430 *==========================================================================*/ 1431int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1432 uint32_t bufLen, 1433 rat_t *gpsTimeStamp, int64_t value) 1434{ 1435 char str[30]; 1436 snprintf(str, sizeof(str), "%lld", value); 1437 if(str != NULL) { 1438 time_t unixTime = (time_t)atol(str); 1439 struct tm *UTCTimestamp = gmtime(&unixTime); 1440 1441 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1442 1443 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1444 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1445 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1446 1447 return NO_ERROR; 1448 } else { 1449 return BAD_VALUE; 1450 } 1451} 1452 1453int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1454 cam_rational_type_t step) 1455{ 1456 exposure_val->num = exposure_comp * step.numerator; 1457 exposure_val->denom = step.denominator; 1458 return 0; 1459} 1460/*=========================================================================== 1461 * FUNCTION : getExifData 1462 * 1463 * DESCRIPTION: get exif data to be passed into jpeg encoding 1464 * 1465 * PARAMETERS : none 1466 * 1467 * RETURN : exif data from user setting and GPS 1468 *==========================================================================*/ 1469QCamera3Exif *QCamera3PicChannel::getExifData() 1470{ 1471 QCamera3Exif *exif = new QCamera3Exif(); 1472 if (exif == NULL) { 1473 ALOGE("%s: No memory for QCamera3Exif", __func__); 1474 return NULL; 1475 } 1476 1477 int32_t rc = NO_ERROR; 1478 uint32_t count = 0; 1479 1480 // add exif entries 1481 char dateTime[20]; 1482 memset(dateTime, 0, sizeof(dateTime)); 1483 count = 20; 1484 rc = getExifDateTime(dateTime, count); 1485 if(rc == NO_ERROR) { 1486 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1487 EXIF_ASCII, 1488 count, 1489 (void *)dateTime); 1490 } else { 1491 ALOGE("%s: getExifDateTime failed", __func__); 1492 } 1493 1494 rat_t focalLength; 1495 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1496 if (rc == NO_ERROR) { 1497 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1498 EXIF_RATIONAL, 1499 1, 1500 (void *)&(focalLength)); 1501 } else { 1502 ALOGE("%s: getExifFocalLength failed", __func__); 1503 } 1504 1505 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity; 1506 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1507 EXIF_SHORT, 1508 1, 1509 (void *)&(isoSpeed)); 1510 1511 1512 if (strlen(mJpegSettings->gps_processing_method) > 0) { 1513 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1514 count = 0; 1515 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1516 if(rc == NO_ERROR) { 1517 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1518 EXIF_ASCII, 1519 count, 1520 (void *)gpsProcessingMethod); 1521 } else { 1522 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1523 } 1524 } 1525 1526 if (mJpegSettings->gps_coordinates[0]) { 1527 rat_t latitude[3]; 1528 char latRef[2]; 1529 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0])); 1530 if(rc == NO_ERROR) { 1531 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1532 EXIF_RATIONAL, 1533 3, 1534 (void *)latitude); 1535 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1536 EXIF_ASCII, 1537 2, 1538 (void *)latRef); 1539 } else { 1540 ALOGE("%s: getExifLatitude failed", __func__); 1541 } 1542 } 1543 1544 if (mJpegSettings->gps_coordinates[1]) { 1545 rat_t longitude[3]; 1546 char lonRef[2]; 1547 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1])); 1548 if(rc == NO_ERROR) { 1549 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1550 EXIF_RATIONAL, 1551 3, 1552 (void *)longitude); 1553 1554 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1555 EXIF_ASCII, 1556 2, 1557 (void *)lonRef); 1558 } else { 1559 ALOGE("%s: getExifLongitude failed", __func__); 1560 } 1561 } 1562 1563 if (mJpegSettings->gps_coordinates[2]) { 1564 rat_t altitude; 1565 char altRef; 1566 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2])); 1567 if(rc == NO_ERROR) { 1568 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1569 EXIF_RATIONAL, 1570 1, 1571 (void *)&(altitude)); 1572 1573 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1574 EXIF_BYTE, 1575 1, 1576 (void *)&altRef); 1577 } else { 1578 ALOGE("%s: getExifAltitude failed", __func__); 1579 } 1580 } 1581 1582 if (mJpegSettings->gps_timestamp) { 1583 char gpsDateStamp[20]; 1584 rat_t gpsTimeStamp[3]; 1585 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp)); 1586 if(rc == NO_ERROR) { 1587 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1588 EXIF_ASCII, 1589 strlen(gpsDateStamp) + 1, 1590 (void *)gpsDateStamp); 1591 1592 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1593 EXIF_RATIONAL, 1594 3, 1595 (void *)gpsTimeStamp); 1596 } else { 1597 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1598 } 1599 } 1600 1601 srat_t exposure_val; 1602 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation, 1603 mJpegSettings->exposure_comp_step); 1604 if(rc == NO_ERROR) { 1605 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1606 EXIF_SRATIONAL, 1607 1, 1608 (void *)(&exposure_val)); 1609 } else { 1610 ALOGE("%s: getExifExposureValue failed ", __func__); 1611 } 1612 1613 char value[PROPERTY_VALUE_MAX]; 1614 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 1615 exif->addEntry(EXIFTAGID_MAKE, 1616 EXIF_ASCII, 1617 strlen(value) + 1, 1618 (void *)value); 1619 } else { 1620 ALOGE("%s: getExifMaker failed", __func__); 1621 } 1622 1623 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 1624 exif->addEntry(EXIFTAGID_MODEL, 1625 EXIF_ASCII, 1626 strlen(value) + 1, 1627 (void *)value); 1628 } else { 1629 ALOGE("%s: getExifModel failed", __func__); 1630 } 1631 1632 return exif; 1633} 1634 1635int QCamera3PicChannel::kMaxBuffers = 2; 1636}; // namespace qcamera 1637