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