QCamera3Channel.cpp revision b66f295ef24aea24873bcf80cee589835338e2a1
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 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 974 streamType = CAM_STREAM_TYPE_SNAPSHOT; 975 streamFormat = CAM_FORMAT_YUV_420_NV21; 976 } else { 977 //TODO: Fail for other types of streams for now 978 ALOGE("%s: format is not BLOB", __func__); 979 return -EINVAL; 980 } 981 /* Bookkeep buffer set because they go out of scope after register call */ 982 mNumBufs = num_buffers; 983 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 984 if (mCamera3Buffers == NULL) { 985 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 986 return -ENOMEM; 987 } 988 for (size_t i = 0; i < num_buffers; i++) 989 mCamera3Buffers[i] = buffers[i]; 990 991 return rc; 992} 993 994void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 995 QCamera3Stream *stream) 996{ 997 //TODO 998 //Used only for getting YUV. Jpeg callback will be sent back from channel directly to HWI. 999 //Refer to func jpegEvtHandle 1000 1001 //Got the yuv callback. Calling yuv callback handler in PostProc 1002 uint8_t frameIndex; 1003 mm_camera_super_buf_t* frame = NULL; 1004 1005 if(!super_frame) { 1006 ALOGE("%s: Invalid Super buffer",__func__); 1007 return; 1008 } 1009 1010 if(super_frame->num_bufs != 1) { 1011 ALOGE("%s: Multiple streams are not supported",__func__); 1012 return; 1013 } 1014 if(super_frame->bufs[0] == NULL ) { 1015 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1016 __func__); 1017 return; 1018 } 1019 1020 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1021 if(frameIndex >= mNumBufs) { 1022 ALOGE("%s: Error, Invalid index for buffer",__func__); 1023 if(stream) { 1024 stream->bufDone(frameIndex); 1025 } 1026 return; 1027 } 1028 1029 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1030 if (frame == NULL) { 1031 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 1032 if(stream) { 1033 stream->bufDone(frameIndex); 1034 } 1035 return; 1036 } 1037 *frame = *super_frame; 1038 1039 m_postprocessor.processData(frame); 1040 return; 1041} 1042 1043QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1044{ 1045 int rc = 0; 1046 1047 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1048 ALOGE("%s: buffers not registered yet", __func__); 1049 return NULL; 1050 } 1051 1052 mMemory = new QCamera3GrallocMemory(); 1053 if (mMemory == NULL) { 1054 return NULL; 1055 } 1056 1057 //Registering Jpeg output buffer 1058 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1059 delete mMemory; 1060 mMemory = NULL; 1061 return NULL; 1062 } 1063 1064 mYuvMemory = new QCamera3HeapMemory(); 1065 if (!mYuvMemory) { 1066 ALOGE("%s: unable to create metadata memory", __func__); 1067 return NULL; 1068 } 1069 1070 //Queue YUV buffers in the beginning mQueueAll = true 1071 rc = mYuvMemory->allocate(QCamera3PicChannel::kMaxBuffers + 1, len, true); 1072 if (rc < 0) { 1073 ALOGE("%s: unable to allocate metadata memory", __func__); 1074 delete mYuvMemory; 1075 mYuvMemory = NULL; 1076 return NULL; 1077 } 1078 return mYuvMemory; 1079} 1080 1081void QCamera3PicChannel::putStreamBufs() 1082{ 1083 mMemory->unregisterBuffers(); 1084 delete mMemory; 1085 mMemory = NULL; 1086 1087 mYuvMemory->deallocate(); 1088 delete mYuvMemory; 1089 mYuvMemory = NULL; 1090} 1091 1092/*=========================================================================== 1093 * FUNCTION : needRotationReprocess 1094 * 1095 * DESCRIPTION: if online rotation needs to be done by cpp 1096 * 1097 * PARAMETERS : none 1098 * 1099 * RETURN : true: needed 1100 * false: no need 1101 *==========================================================================*/ 1102bool QCamera3PicChannel::needOnlineRotation() 1103{ 1104 //TBD_Later 1105 //if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 && 1106 if (mJpegSettings->jpeg_orientation > 0) { 1107 // current rotation is not zero, and pp has the capability to process rotation 1108 ALOGD("%s: need do online rotation", __func__); 1109 return true; 1110 } 1111 return false; 1112} 1113 1114/*=========================================================================== 1115 * FUNCTION : getThumbnailSize 1116 * 1117 * DESCRIPTION: get user set thumbnail size 1118 * 1119 * PARAMETERS : 1120 * @dim : output of thumbnail dimension 1121 * 1122 * RETURN : none 1123 *==========================================================================*/ 1124void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1125{ 1126 dim = mJpegSettings->thumbnail_size; 1127} 1128 1129/*=========================================================================== 1130 * FUNCTION : getJpegQuality 1131 * 1132 * DESCRIPTION: get user set jpeg quality 1133 * 1134 * PARAMETERS : none 1135 * 1136 * RETURN : jpeg quality setting 1137 *==========================================================================*/ 1138int QCamera3PicChannel::getJpegQuality() 1139{ 1140 int quality = mJpegSettings->jpeg_quality; 1141 if (quality < 0) { 1142 quality = 85; //set to default quality value 1143 } 1144 return quality; 1145} 1146 1147/*=========================================================================== 1148 * FUNCTION : getJpegRotation 1149 * 1150 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1151 * 1152 * PARAMETERS : none 1153 * 1154 * RETURN : rotation information 1155 *==========================================================================*/ 1156int QCamera3PicChannel::getJpegRotation() { 1157 int rotation = mJpegSettings->jpeg_orientation; 1158 if (rotation < 0) { 1159 rotation = 0; 1160 } 1161 return rotation; 1162} 1163 1164/*=========================================================================== 1165 * FUNCTION : getRational 1166 * 1167 * DESCRIPTION: compose rational struct 1168 * 1169 * PARAMETERS : 1170 * @rat : ptr to struct to store rational info 1171 * @num :num of the rational 1172 * @denom : denom of the rational 1173 * 1174 * RETURN : int32_t type of status 1175 * NO_ERROR -- success 1176 * none-zero failure code 1177 *==========================================================================*/ 1178int32_t getRational(rat_t *rat, int num, int denom) 1179{ 1180 if (NULL == rat) { 1181 ALOGE("%s: NULL rat input", __func__); 1182 return BAD_VALUE; 1183 } 1184 rat->num = num; 1185 rat->denom = denom; 1186 return NO_ERROR; 1187} 1188 1189/*=========================================================================== 1190 * FUNCTION : parseGPSCoordinate 1191 * 1192 * DESCRIPTION: parse GPS coordinate string 1193 * 1194 * PARAMETERS : 1195 * @coord_str : [input] coordinate string 1196 * @coord : [output] ptr to struct to store coordinate 1197 * 1198 * RETURN : int32_t type of status 1199 * NO_ERROR -- success 1200 * none-zero failure code 1201 *==========================================================================*/ 1202int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1203{ 1204 if(coord == NULL) { 1205 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1206 return BAD_VALUE; 1207 } 1208 float degF = atof(coord_str); 1209 if (degF < 0) { 1210 degF = -degF; 1211 } 1212 float minF = (degF - (int) degF) * 60; 1213 float secF = (minF - (int) minF) * 60; 1214 1215 getRational(&coord[0], (int)degF, 1); 1216 getRational(&coord[1], (int)minF, 1); 1217 getRational(&coord[2], (int)(secF * 10000), 10000); 1218 return NO_ERROR; 1219} 1220 1221/*=========================================================================== 1222 * FUNCTION : getExifDateTime 1223 * 1224 * DESCRIPTION: query exif date time 1225 * 1226 * PARAMETERS : 1227 * @dateTime : string to store exif date time 1228 * @count : lenght of the dateTime string 1229 * 1230 * RETURN : int32_t type of status 1231 * NO_ERROR -- success 1232 * none-zero failure code 1233 *==========================================================================*/ 1234int32_t getExifDateTime(char *dateTime, uint32_t &count) 1235{ 1236 //get time and date from system 1237 time_t rawtime; 1238 struct tm * timeinfo; 1239 time(&rawtime); 1240 timeinfo = localtime (&rawtime); 1241 //Write datetime according to EXIF Spec 1242 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1243 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1244 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1245 timeinfo->tm_mday, timeinfo->tm_hour, 1246 timeinfo->tm_min, timeinfo->tm_sec); 1247 count = 20; 1248 1249 return NO_ERROR; 1250} 1251 1252/*=========================================================================== 1253 * FUNCTION : getExifFocalLength 1254 * 1255 * DESCRIPTION: get exif focal lenght 1256 * 1257 * PARAMETERS : 1258 * @focalLength : ptr to rational strcut to store focal lenght 1259 * 1260 * RETURN : int32_t type of status 1261 * NO_ERROR -- success 1262 * none-zero failure code 1263 *==========================================================================*/ 1264int32_t getExifFocalLength(rat_t *focalLength, float value) 1265{ 1266 int focalLengthValue = 1267 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1268 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1269} 1270 1271/*=========================================================================== 1272 * FUNCTION : getExifGpsProcessingMethod 1273 * 1274 * DESCRIPTION: get GPS processing method 1275 * 1276 * PARAMETERS : 1277 * @gpsProcessingMethod : string to store GPS process method 1278 * @count : lenght of the string 1279 * 1280 * RETURN : int32_t type of status 1281 * NO_ERROR -- success 1282 * none-zero failure code 1283 *==========================================================================*/ 1284int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1285 uint32_t &count, int value) 1286{ 1287 char str[30]; 1288 snprintf(str, sizeof(str), "%d", value); 1289 if(str != NULL) { 1290 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1291 count = EXIF_ASCII_PREFIX_SIZE; 1292 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str, strlen(str)); 1293 count += strlen(str); 1294 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1295 return NO_ERROR; 1296 } else { 1297 return BAD_VALUE; 1298 } 1299} 1300 1301/*=========================================================================== 1302 * FUNCTION : getExifLatitude 1303 * 1304 * DESCRIPTION: get exif latitude 1305 * 1306 * PARAMETERS : 1307 * @latitude : ptr to rational struct to store latitude info 1308 * @ladRef : charater to indicate latitude reference 1309 * 1310 * RETURN : int32_t type of status 1311 * NO_ERROR -- success 1312 * none-zero failure code 1313 *==========================================================================*/ 1314int32_t getExifLatitude(rat_t *latitude, 1315 char *latRef, double value) 1316{ 1317 char str[30]; 1318 snprintf(str, sizeof(str), "%f", value); 1319 if(str != NULL) { 1320 parseGPSCoordinate(str, latitude); 1321 1322 //set Latitude Ref 1323 float latitudeValue = strtof(str, 0); 1324 if(latitudeValue < 0.0f) { 1325 latRef[0] = 'S'; 1326 } else { 1327 latRef[0] = 'N'; 1328 } 1329 latRef[1] = '\0'; 1330 return NO_ERROR; 1331 }else{ 1332 return BAD_VALUE; 1333 } 1334} 1335 1336/*=========================================================================== 1337 * FUNCTION : getExifLongitude 1338 * 1339 * DESCRIPTION: get exif longitude 1340 * 1341 * PARAMETERS : 1342 * @longitude : ptr to rational struct to store longitude info 1343 * @lonRef : charater to indicate longitude reference 1344 * 1345 * RETURN : int32_t type of status 1346 * NO_ERROR -- success 1347 * none-zero failure code 1348 *==========================================================================*/ 1349int32_t getExifLongitude(rat_t *longitude, 1350 char *lonRef, double value) 1351{ 1352 char str[30]; 1353 snprintf(str, sizeof(str), "%f", value); 1354 if(str != NULL) { 1355 parseGPSCoordinate(str, longitude); 1356 1357 //set Longitude Ref 1358 float longitudeValue = strtof(str, 0); 1359 if(longitudeValue < 0.0f) { 1360 lonRef[0] = 'W'; 1361 } else { 1362 lonRef[0] = 'E'; 1363 } 1364 lonRef[1] = '\0'; 1365 return NO_ERROR; 1366 }else{ 1367 return BAD_VALUE; 1368 } 1369} 1370 1371/*=========================================================================== 1372 * FUNCTION : getExifAltitude 1373 * 1374 * DESCRIPTION: get exif altitude 1375 * 1376 * PARAMETERS : 1377 * @altitude : ptr to rational struct to store altitude info 1378 * @altRef : charater to indicate altitude reference 1379 * 1380 * RETURN : int32_t type of status 1381 * NO_ERROR -- success 1382 * none-zero failure code 1383 *==========================================================================*/ 1384int32_t getExifAltitude(rat_t *altitude, 1385 char *altRef, double value) 1386{ 1387 char str[30]; 1388 snprintf(str, sizeof(str), "%f", value); 1389 if(str != NULL) { 1390 double value = atof(str); 1391 *altRef = 0; 1392 if(value < 0){ 1393 *altRef = 1; 1394 value = -value; 1395 } 1396 return getRational(altitude, value*1000, 1000); 1397 }else{ 1398 return BAD_VALUE; 1399 } 1400} 1401 1402/*=========================================================================== 1403 * FUNCTION : getExifGpsDateTimeStamp 1404 * 1405 * DESCRIPTION: get exif GPS date time stamp 1406 * 1407 * PARAMETERS : 1408 * @gpsDateStamp : GPS date time stamp string 1409 * @bufLen : length of the string 1410 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1411 * 1412 * RETURN : int32_t type of status 1413 * NO_ERROR -- success 1414 * none-zero failure code 1415 *==========================================================================*/ 1416int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1417 uint32_t bufLen, 1418 rat_t *gpsTimeStamp, int64_t value) 1419{ 1420 char str[30]; 1421 snprintf(str, sizeof(str), "%d", value); 1422 if(str != NULL) { 1423 time_t unixTime = (time_t)atol(str); 1424 struct tm *UTCTimestamp = gmtime(&unixTime); 1425 1426 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1427 1428 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1429 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1430 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1431 1432 return NO_ERROR; 1433 } else { 1434 return BAD_VALUE; 1435 } 1436} 1437/*=========================================================================== 1438 * FUNCTION : getExifData 1439 * 1440 * DESCRIPTION: get exif data to be passed into jpeg encoding 1441 * 1442 * PARAMETERS : none 1443 * 1444 * RETURN : exif data from user setting and GPS 1445 *==========================================================================*/ 1446QCamera3Exif *QCamera3PicChannel::getExifData() 1447{ 1448 QCamera3Exif *exif = new QCamera3Exif(); 1449 if (exif == NULL) { 1450 ALOGE("%s: No memory for QCamera3Exif", __func__); 1451 return NULL; 1452 } 1453 1454 int32_t rc = NO_ERROR; 1455 uint32_t count = 0; 1456 1457 // add exif entries 1458 char dateTime[20]; 1459 memset(dateTime, 0, sizeof(dateTime)); 1460 count = 20; 1461 rc = getExifDateTime(dateTime, count); 1462 if(rc == NO_ERROR) { 1463 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1464 EXIF_ASCII, 1465 count, 1466 (void *)dateTime); 1467 } else { 1468 ALOGE("%s: getExifDateTime failed", __func__); 1469 } 1470 1471 rat_t focalLength; 1472 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1473 if (rc == NO_ERROR) { 1474 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1475 EXIF_RATIONAL, 1476 1, 1477 (void *)&(focalLength)); 1478 } else { 1479 ALOGE("%s: getExifFocalLength failed", __func__); 1480 } 1481 1482 //TBD_Later 1483 /*uint16_t isoSpeed = mParameters.getExifIsoSpeed(); 1484 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1485 EXIF_SHORT, 1486 1, 1487 (void *)&(isoSpeed)); 1488 */ 1489 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1490 count = 0; 1491 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1492 if(rc == NO_ERROR) { 1493 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1494 EXIF_ASCII, 1495 count, 1496 (void *)gpsProcessingMethod); 1497 } else { 1498 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1499 } 1500 1501 rat_t latitude[3]; 1502 char latRef[2]; 1503 rc = getExifLatitude(latitude, latRef, mJpegSettings->gps_coordinates[0]); 1504 if(rc == NO_ERROR) { 1505 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1506 EXIF_RATIONAL, 1507 3, 1508 (void *)latitude); 1509 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1510 EXIF_ASCII, 1511 2, 1512 (void *)latRef); 1513 } else { 1514 ALOGE("%s: getExifLatitude failed", __func__); 1515 } 1516 1517 rat_t longitude[3]; 1518 char lonRef[2]; 1519 rc = getExifLongitude(longitude, lonRef, mJpegSettings->gps_coordinates[1]); 1520 if(rc == NO_ERROR) { 1521 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1522 EXIF_RATIONAL, 1523 3, 1524 (void *)longitude); 1525 1526 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1527 EXIF_ASCII, 1528 2, 1529 (void *)lonRef); 1530 } else { 1531 ALOGE("%s: getExifLongitude failed", __func__); 1532 } 1533 1534 rat_t altitude; 1535 char altRef; 1536 rc = getExifAltitude(&altitude, &altRef, mJpegSettings->gps_coordinates[2]); 1537 if(rc == NO_ERROR) { 1538 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1539 EXIF_RATIONAL, 1540 1, 1541 (void *)&(altitude)); 1542 1543 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1544 EXIF_BYTE, 1545 1, 1546 (void *)&altRef); 1547 } else { 1548 ALOGE("%s: getExifAltitude failed", __func__); 1549 } 1550 1551 char gpsDateStamp[20]; 1552 rat_t gpsTimeStamp[3]; 1553 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, mJpegSettings->gps_timestamp); 1554 if(rc == NO_ERROR) { 1555 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1556 EXIF_ASCII, 1557 strlen(gpsDateStamp) + 1, 1558 (void *)gpsDateStamp); 1559 1560 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1561 EXIF_RATIONAL, 1562 3, 1563 (void *)gpsTimeStamp); 1564 } else { 1565 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1566 } 1567 1568 return exif; 1569} 1570 1571int QCamera3PicChannel::kMaxBuffers = 1; 1572}; // namespace qcamera 1573