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