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