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 <cutils/properties.h> 35 #include <stdio.h> 36 #include <string.h> 37 #include <hardware/camera3.h> 38 #include <math.h> 39 #include <system/camera_metadata.h> 40 #include <gralloc_priv.h> 41 #include <utils/Log.h> 42 #include <utils/Errors.h> 43 #include <cutils/properties.h> 44 #include "QCamera3Channel.h" 45 46 using namespace android; 47 48 #define MIN_STREAMING_BUFFER_NUM 7 49 50 namespace qcamera { 51 static const char ExifAsciiPrefix[] = 52 { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; // "ASCII\0\0\0" 53 static const char ExifUndefinedPrefix[] = 54 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // "\0\0\0\0\0\0\0\0" 55 56 #define GPS_PROCESSING_METHOD_SIZE 101 57 #define EXIF_ASCII_PREFIX_SIZE 8 //(sizeof(ExifAsciiPrefix)) 58 #define FOCAL_LENGTH_DECIMAL_PRECISION 100 59 60 /*=========================================================================== 61 * FUNCTION : QCamera3Channel 62 * 63 * DESCRIPTION: constrcutor of QCamera3Channel 64 * 65 * PARAMETERS : 66 * @cam_handle : camera handle 67 * @cam_ops : ptr to camera ops table 68 * 69 * RETURN : none 70 *==========================================================================*/ 71 QCamera3Channel::QCamera3Channel(uint32_t cam_handle, 72 mm_camera_ops_t *cam_ops, 73 channel_cb_routine cb_routine, 74 cam_padding_info_t *paddingInfo, 75 void *userData) 76 { 77 m_camHandle = cam_handle; 78 m_camOps = cam_ops; 79 m_bIsActive = false; 80 81 m_handle = 0; 82 m_numStreams = 0; 83 memset(mStreams, 0, sizeof(mStreams)); 84 mUserData = userData; 85 86 mStreamInfoBuf = NULL; 87 mChannelCB = cb_routine; 88 mPaddingInfo = paddingInfo; 89 } 90 91 /*=========================================================================== 92 * FUNCTION : QCamera3Channel 93 * 94 * DESCRIPTION: default constrcutor of QCamera3Channel 95 * 96 * PARAMETERS : none 97 * 98 * RETURN : none 99 *==========================================================================*/ 100 QCamera3Channel::QCamera3Channel() 101 { 102 m_camHandle = 0; 103 m_camOps = NULL; 104 m_bIsActive = false; 105 106 m_handle = 0; 107 m_numStreams = 0; 108 memset(mStreams, 0, sizeof(mStreams)); 109 mUserData = NULL; 110 111 mStreamInfoBuf = NULL; 112 mChannelCB = NULL; 113 mPaddingInfo = NULL; 114 } 115 116 /*=========================================================================== 117 * FUNCTION : ~QCamera3Channel 118 * 119 * DESCRIPTION: destructor of QCamera3Channel 120 * 121 * PARAMETERS : none 122 * 123 * RETURN : none 124 *==========================================================================*/ 125 QCamera3Channel::~QCamera3Channel() 126 { 127 if (m_bIsActive) 128 stop(); 129 130 for (int i = 0; i < m_numStreams; i++) { 131 if (mStreams[i] != NULL) { 132 delete mStreams[i]; 133 mStreams[i] = 0; 134 } 135 } 136 if (m_handle) { 137 m_camOps->delete_channel(m_camHandle, m_handle); 138 ALOGE("%s: deleting channel %d", __func__, m_handle); 139 m_handle = 0; 140 } 141 m_numStreams = 0; 142 } 143 144 /*=========================================================================== 145 * FUNCTION : init 146 * 147 * DESCRIPTION: initialization of channel 148 * 149 * PARAMETERS : 150 * @attr : channel bundle attribute setting 151 * @dataCB : data notify callback 152 * @userData: user data ptr 153 * 154 * RETURN : int32_t type of status 155 * NO_ERROR -- success 156 * none-zero failure code 157 *==========================================================================*/ 158 int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr, 159 mm_camera_buf_notify_t dataCB) 160 { 161 m_handle = m_camOps->add_channel(m_camHandle, 162 attr, 163 dataCB, 164 this); 165 if (m_handle == 0) { 166 ALOGE("%s: Add channel failed", __func__); 167 return UNKNOWN_ERROR; 168 } 169 return NO_ERROR; 170 } 171 172 /*=========================================================================== 173 * FUNCTION : addStream 174 * 175 * DESCRIPTION: add a stream into channel 176 * 177 * PARAMETERS : 178 * @allocator : stream related buffer allocator 179 * @streamInfoBuf : ptr to buf that constains stream info 180 * @minStreamBufNum: number of stream buffers needed 181 * @paddingInfo : padding information 182 * @stream_cb : stream data notify callback 183 * @userdata : user data ptr 184 * 185 * RETURN : int32_t type of status 186 * NO_ERROR -- success 187 * none-zero failure code 188 *==========================================================================*/ 189 int32_t QCamera3Channel::addStream(cam_stream_type_t streamType, 190 cam_format_t streamFormat, 191 cam_dimension_t streamDim, 192 uint8_t minStreamBufNum) 193 { 194 int32_t rc = NO_ERROR; 195 196 if (m_numStreams >= 1) { 197 ALOGE("%s: Only one stream per channel supported in v3 Hal", __func__); 198 return BAD_VALUE; 199 } 200 201 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) { 202 ALOGE("%s: stream number (%d) exceeds max limit (%d)", 203 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE); 204 return BAD_VALUE; 205 } 206 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 207 m_handle, 208 m_camOps, 209 mPaddingInfo, 210 this); 211 if (pStream == NULL) { 212 ALOGE("%s: No mem for Stream", __func__); 213 return NO_MEMORY; 214 } 215 216 rc = pStream->init(streamType, streamFormat, streamDim, NULL, minStreamBufNum, 217 streamCbRoutine, this); 218 if (rc == 0) { 219 mStreams[m_numStreams] = pStream; 220 m_numStreams++; 221 } else { 222 delete pStream; 223 } 224 return rc; 225 } 226 227 /*=========================================================================== 228 * FUNCTION : start 229 * 230 * DESCRIPTION: start channel, which will start all streams belong to this channel 231 * 232 * PARAMETERS : 233 * 234 * RETURN : int32_t type of status 235 * NO_ERROR -- success 236 * none-zero failure code 237 *==========================================================================*/ 238 int32_t QCamera3Channel::start() 239 { 240 int32_t rc = NO_ERROR; 241 242 if (m_numStreams > 1) { 243 ALOGE("%s: bundle not supported", __func__); 244 } 245 246 for (int i = 0; i < m_numStreams; i++) { 247 if (mStreams[i] != NULL) { 248 mStreams[i]->start(); 249 } 250 } 251 rc = m_camOps->start_channel(m_camHandle, m_handle); 252 253 if (rc != NO_ERROR) { 254 for (int i = 0; i < m_numStreams; i++) { 255 if (mStreams[i] != NULL) { 256 mStreams[i]->stop(); 257 } 258 } 259 } else { 260 m_bIsActive = true; 261 } 262 263 return rc; 264 } 265 266 /*=========================================================================== 267 * FUNCTION : stop 268 * 269 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 270 * 271 * PARAMETERS : none 272 * 273 * RETURN : int32_t type of status 274 * NO_ERROR -- success 275 * none-zero failure code 276 *==========================================================================*/ 277 int32_t QCamera3Channel::stop() 278 { 279 int32_t rc = NO_ERROR; 280 if(!m_bIsActive) { 281 ALOGE("%s: Attempt to stop inactive channel",__func__); 282 return rc; 283 } 284 285 rc = m_camOps->stop_channel(m_camHandle, m_handle); 286 287 for (int i = 0; i < m_numStreams; i++) { 288 if (mStreams[i] != NULL) { 289 mStreams[i]->stop(); 290 } 291 } 292 293 m_bIsActive = false; 294 return rc; 295 } 296 297 /*=========================================================================== 298 * FUNCTION : bufDone 299 * 300 * DESCRIPTION: return a stream buf back to kernel 301 * 302 * PARAMETERS : 303 * @recvd_frame : stream buf frame to be returned 304 * 305 * RETURN : int32_t type of status 306 * NO_ERROR -- success 307 * none-zero failure code 308 *==========================================================================*/ 309 int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame) 310 { 311 int32_t rc = NO_ERROR; 312 for (int i = 0; i < recvd_frame->num_bufs; i++) { 313 if (recvd_frame->bufs[i] != NULL) { 314 for (int j = 0; j < m_numStreams; j++) { 315 if (mStreams[j] != NULL && 316 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 317 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 318 break; // break loop j 319 } 320 } 321 } 322 } 323 324 return rc; 325 } 326 327 /*=========================================================================== 328 * FUNCTION : getStreamTypeMask 329 * 330 * DESCRIPTION: Get bit mask of all stream types in this channel 331 * 332 * PARAMETERS : None 333 * 334 * RETURN : Bit mask of all stream types in this channel 335 *==========================================================================*/ 336 uint32_t QCamera3Channel::getStreamTypeMask() 337 { 338 uint32_t mask = 0; 339 for (int i = 0; i < m_numStreams; i++) { 340 mask |= (0x1 << mStreams[i]->getMyType()); 341 } 342 return mask; 343 } 344 345 /*=========================================================================== 346 * FUNCTION : getInternalFormatBuffer 347 * 348 * DESCRIPTION: return buffer in the internal format structure 349 * 350 * PARAMETERS : 351 * @streamHandle : buffer handle 352 * 353 * RETURN : stream object. NULL if not found 354 *==========================================================================*/ 355 mm_camera_buf_def_t* QCamera3RegularChannel::getInternalFormatBuffer( 356 buffer_handle_t * buffer) 357 { 358 int32_t index; 359 if(buffer == NULL) 360 return NULL; 361 index = mMemory->getMatchBufIndex((void*)buffer); 362 if(index < 0) { 363 ALOGE("%s: Could not find object among registered buffers",__func__); 364 return NULL; 365 } 366 return mStreams[0]->getInternalFormatBuffer(index); 367 } 368 369 /*=========================================================================== 370 * FUNCTION : getStreamByHandle 371 * 372 * DESCRIPTION: return stream object by stream handle 373 * 374 * PARAMETERS : 375 * @streamHandle : stream handle 376 * 377 * RETURN : stream object. NULL if not found 378 *==========================================================================*/ 379 QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle) 380 { 381 for (int i = 0; i < m_numStreams; i++) { 382 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 383 return mStreams[i]; 384 } 385 } 386 return NULL; 387 } 388 389 /*=========================================================================== 390 * FUNCTION : getStreamByIndex 391 * 392 * DESCRIPTION: return stream object by index 393 * 394 * PARAMETERS : 395 * @streamHandle : stream handle 396 * 397 * RETURN : stream object. NULL if not found 398 *==========================================================================*/ 399 QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index) 400 { 401 if (index < m_numStreams) { 402 return mStreams[index]; 403 } 404 return NULL; 405 } 406 407 /*=========================================================================== 408 * FUNCTION : streamCbRoutine 409 * 410 * DESCRIPTION: callback routine for stream 411 * 412 * PARAMETERS : 413 * @streamHandle : stream handle 414 * 415 * RETURN : stream object. NULL if not found 416 *==========================================================================*/ 417 void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 418 QCamera3Stream *stream, void *userdata) 419 { 420 QCamera3Channel *channel = (QCamera3Channel *)userdata; 421 if (channel == NULL) { 422 ALOGE("%s: invalid channel pointer", __func__); 423 return; 424 } 425 channel->streamCbRoutine(super_frame, stream); 426 } 427 428 /*=========================================================================== 429 * FUNCTION : QCamera3RegularChannel 430 * 431 * DESCRIPTION: constrcutor of QCamera3RegularChannel 432 * 433 * PARAMETERS : 434 * @cam_handle : camera handle 435 * @cam_ops : ptr to camera ops table 436 * @cb_routine : callback routine to frame aggregator 437 * @stream : camera3_stream_t structure 438 * 439 * RETURN : none 440 *==========================================================================*/ 441 QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 442 mm_camera_ops_t *cam_ops, 443 channel_cb_routine cb_routine, 444 cam_padding_info_t *paddingInfo, 445 void *userData, 446 camera3_stream_t *stream) : 447 QCamera3Channel(cam_handle, cam_ops, cb_routine, 448 paddingInfo, userData), 449 mCamera3Stream(stream), 450 mNumBufs(0), 451 mCamera3Buffers(NULL), 452 mMemory(NULL), 453 mWidth(stream->width), 454 mHeight(stream->height) 455 { 456 } 457 458 /*=========================================================================== 459 * FUNCTION : QCamera3RegularChannel 460 * 461 * DESCRIPTION: constrcutor of QCamera3RegularChannel 462 * 463 * PARAMETERS : 464 * @cam_handle : camera handle 465 * @cam_ops : ptr to camera ops table 466 * @cb_routine : callback routine to frame aggregator 467 * @stream : camera3_stream_t structure 468 * 469 * RETURN : none 470 *==========================================================================*/ 471 QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 472 mm_camera_ops_t *cam_ops, 473 channel_cb_routine cb_routine, 474 cam_padding_info_t *paddingInfo, 475 void *userData, 476 camera3_stream_t *stream, 477 uint32_t width, uint32_t height) : 478 QCamera3Channel(cam_handle, cam_ops, cb_routine, 479 paddingInfo, userData), 480 mCamera3Stream(stream), 481 mNumBufs(0), 482 mCamera3Buffers(NULL), 483 mMemory(NULL), 484 mWidth(width), 485 mHeight(height) 486 { 487 } 488 489 /*=========================================================================== 490 * FUNCTION : ~QCamera3RegularChannel 491 * 492 * DESCRIPTION: destructor of QCamera3RegularChannel 493 * 494 * PARAMETERS : none 495 * 496 * RETURN : none 497 *==========================================================================*/ 498 QCamera3RegularChannel::~QCamera3RegularChannel() 499 { 500 if (mCamera3Buffers) { 501 delete[] mCamera3Buffers; 502 } 503 } 504 505 int32_t QCamera3RegularChannel::initialize() 506 { 507 //TO DO 508 return 0; 509 } 510 511 /*=========================================================================== 512 * FUNCTION : request 513 * 514 * DESCRIPTION: process a request from camera service. Stream on if ncessary. 515 * 516 * PARAMETERS : 517 * @buffer : buffer to be filled for this request 518 * 519 * RETURN : 0 on a success start of capture 520 * -EINVAL on invalid input 521 * -ENODEV on serious error 522 *==========================================================================*/ 523 int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber) 524 { 525 //FIX ME: Return buffer back in case of failures below. 526 527 int32_t rc = NO_ERROR; 528 int index; 529 if(!m_bIsActive) { 530 ALOGD("%s: First request on this channel starting stream",__func__); 531 start(); 532 if(rc != NO_ERROR) { 533 ALOGE("%s: Failed to start the stream on the request",__func__); 534 return rc; 535 } 536 } else { 537 ALOGV("%s: Request on an existing stream",__func__); 538 } 539 540 if(!mMemory) { 541 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 542 return NO_MEMORY; 543 } 544 545 index = mMemory->getMatchBufIndex((void*)buffer); 546 if(index < 0) { 547 ALOGE("%s: Could not find object among registered buffers",__func__); 548 return DEAD_OBJECT; 549 } 550 551 rc = mStreams[0]->bufDone(index); 552 if(rc != NO_ERROR) { 553 ALOGE("%s: Failed to Q new buffer to stream",__func__); 554 return rc; 555 } 556 557 rc = mMemory->markFrameNumber(index, frameNumber); 558 return rc; 559 } 560 561 /*=========================================================================== 562 * FUNCTION : registerBuffers 563 * 564 * DESCRIPTION: register streaming buffers to the channel object 565 * 566 * PARAMETERS : 567 * @num_buffers : number of buffers to be registered 568 * @buffers : buffer to be registered 569 * 570 * RETURN : 0 on a success start of capture 571 * -EINVAL on invalid input 572 * -ENOMEM on failure to register the buffer 573 * -ENODEV on serious error 574 *==========================================================================*/ 575 int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 576 { 577 int rc = 0; 578 struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]); 579 cam_stream_type_t streamType; 580 cam_format_t streamFormat; 581 cam_dimension_t streamDim; 582 583 rc = init(NULL, NULL); 584 if (rc < 0) { 585 ALOGE("%s: init failed", __func__); 586 return rc; 587 } 588 589 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 590 if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) { 591 streamType = CAM_STREAM_TYPE_VIDEO; 592 streamFormat = CAM_FORMAT_YUV_420_NV12; 593 } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) { 594 streamType = CAM_STREAM_TYPE_PREVIEW; 595 streamFormat = CAM_FORMAT_YUV_420_NV21; 596 } else { 597 //TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs 598 // to be properly aligned and padded. 599 ALOGE("%s: priv_handle->flags 0x%x not supported", 600 __func__, priv_handle->flags); 601 streamType = CAM_STREAM_TYPE_SNAPSHOT; 602 streamFormat = CAM_FORMAT_YUV_420_NV21; 603 } 604 } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 605 streamType = CAM_STREAM_TYPE_CALLBACK; 606 streamFormat = CAM_FORMAT_YUV_420_NV21; 607 } else { 608 //TODO: Fail for other types of streams for now 609 ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__); 610 return -EINVAL; 611 } 612 613 /* Bookkeep buffer set because they go out of scope after register call */ 614 mNumBufs = num_buffers; 615 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 616 if (mCamera3Buffers == NULL) { 617 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 618 return -ENOMEM; 619 } 620 for (size_t i = 0; i < num_buffers; i++) 621 mCamera3Buffers[i] = buffers[i]; 622 623 streamDim.width = mWidth; 624 streamDim.height = mHeight; 625 626 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 627 num_buffers); 628 return rc; 629 } 630 631 void QCamera3RegularChannel::streamCbRoutine( 632 mm_camera_super_buf_t *super_frame, 633 QCamera3Stream *stream) 634 { 635 //FIXME Q Buf back in case of error? 636 uint8_t frameIndex; 637 buffer_handle_t *resultBuffer; 638 int32_t resultFrameNumber; 639 camera3_stream_buffer_t result; 640 641 if(!super_frame) { 642 ALOGE("%s: Invalid Super buffer",__func__); 643 return; 644 } 645 646 if(super_frame->num_bufs != 1) { 647 ALOGE("%s: Multiple streams are not supported",__func__); 648 return; 649 } 650 if(super_frame->bufs[0] == NULL ) { 651 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 652 __func__); 653 return; 654 } 655 656 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 657 if(frameIndex >= mNumBufs) { 658 ALOGE("%s: Error, Invalid index for buffer",__func__); 659 if(stream) { 660 stream->bufDone(frameIndex); 661 } 662 return; 663 } 664 665 ////Use below data to issue framework callback 666 resultBuffer = mCamera3Buffers[frameIndex]; 667 resultFrameNumber = mMemory->getFrameNumber(frameIndex); 668 669 result.stream = mCamera3Stream; 670 result.buffer = resultBuffer; 671 result.status = CAMERA3_BUFFER_STATUS_OK; 672 result.acquire_fence = -1; 673 result.release_fence = -1; 674 675 mChannelCB(NULL, &result, resultFrameNumber, mUserData); 676 free(super_frame); 677 return; 678 } 679 680 QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/) 681 { 682 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 683 ALOGE("%s: buffers not registered yet", __func__); 684 return NULL; 685 } 686 687 mMemory = new QCamera3GrallocMemory(); 688 if (mMemory == NULL) { 689 return NULL; 690 } 691 692 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 693 delete mMemory; 694 mMemory = NULL; 695 return NULL; 696 } 697 return mMemory; 698 } 699 700 void QCamera3RegularChannel::putStreamBufs() 701 { 702 mMemory->unregisterBuffers(); 703 delete mMemory; 704 mMemory = NULL; 705 } 706 707 int QCamera3RegularChannel::kMaxBuffers = 7; 708 709 QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle, 710 mm_camera_ops_t *cam_ops, 711 channel_cb_routine cb_routine, 712 cam_padding_info_t *paddingInfo, 713 void *userData) : 714 QCamera3Channel(cam_handle, cam_ops, 715 cb_routine, paddingInfo, userData), 716 mMemory(NULL) 717 { 718 } 719 720 QCamera3MetadataChannel::~QCamera3MetadataChannel() 721 { 722 if (m_bIsActive) 723 stop(); 724 725 if (mMemory) { 726 mMemory->deallocate(); 727 delete mMemory; 728 mMemory = NULL; 729 } 730 } 731 732 int32_t QCamera3MetadataChannel::initialize() 733 { 734 int32_t rc; 735 cam_dimension_t streamDim; 736 737 if (mMemory || m_numStreams > 0) { 738 ALOGE("%s: metadata channel already initialized", __func__); 739 return -EINVAL; 740 } 741 742 rc = init(NULL, NULL); 743 if (rc < 0) { 744 ALOGE("%s: init failed", __func__); 745 return rc; 746 } 747 748 streamDim.width = sizeof(metadata_buffer_t), 749 streamDim.height = 1; 750 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX, 751 streamDim, MIN_STREAMING_BUFFER_NUM); 752 if (rc < 0) { 753 ALOGE("%s: addStream failed", __func__); 754 } 755 return rc; 756 } 757 758 int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/, 759 uint32_t /*frameNumber*/) 760 { 761 if (!m_bIsActive) { 762 return start(); 763 } 764 else 765 return 0; 766 } 767 768 int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/, 769 buffer_handle_t ** /*buffers*/) 770 { 771 // no registerBuffers are supported for metadata channel 772 return -EINVAL; 773 } 774 775 void QCamera3MetadataChannel::streamCbRoutine( 776 mm_camera_super_buf_t *super_frame, 777 QCamera3Stream *stream) 778 { 779 uint32_t requestNumber = 0; 780 if (super_frame == NULL || super_frame->num_bufs != 1) { 781 ALOGE("%s: super_frame is not valid", __func__); 782 return; 783 } 784 mChannelCB(super_frame, NULL, requestNumber, mUserData); 785 } 786 787 QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len) 788 { 789 int rc; 790 if (len < sizeof(metadata_buffer_t)) { 791 ALOGE("%s: size doesn't match %d vs %d", __func__, 792 len, sizeof(metadata_buffer_t)); 793 return NULL; 794 } 795 mMemory = new QCamera3HeapMemory(); 796 if (!mMemory) { 797 ALOGE("%s: unable to create metadata memory", __func__); 798 return NULL; 799 } 800 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true); 801 if (rc < 0) { 802 ALOGE("%s: unable to allocate metadata memory", __func__); 803 delete mMemory; 804 mMemory = NULL; 805 return NULL; 806 } 807 memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t)); 808 return mMemory; 809 } 810 811 void QCamera3MetadataChannel::putStreamBufs() 812 { 813 mMemory->deallocate(); 814 delete mMemory; 815 mMemory = NULL; 816 } 817 818 /*=========================================================================== 819 * FUNCTION : jpegEvtHandle 820 * 821 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events. 822 Construct result payload and call mChannelCb to deliver buffer 823 to framework. 824 * 825 * PARAMETERS : 826 * @status : status of jpeg job 827 * @client_hdl: jpeg client handle 828 * @jobId : jpeg job Id 829 * @p_ouput : ptr to jpeg output result struct 830 * @userdata : user data ptr 831 * 832 * RETURN : none 833 *==========================================================================*/ 834 void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status, 835 uint32_t /*client_hdl*/, 836 uint32_t jobId, 837 mm_jpeg_output_t *p_output, 838 void *userdata) 839 { 840 buffer_handle_t *resultBuffer; 841 int32_t resultFrameNumber; 842 int resultStatus = CAMERA3_BUFFER_STATUS_OK; 843 camera3_stream_buffer_t result; 844 camera3_jpeg_blob_t jpegHeader; 845 char* jpeg_eof = 0; 846 int maxJpegSize; 847 QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata; 848 if (obj) { 849 //Construct payload for process_capture_result. Call mChannelCb 850 851 qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId); 852 853 if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) { 854 ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status); 855 resultStatus = CAMERA3_BUFFER_STATUS_ERROR; 856 } 857 858 //Construct jpeg transient header of type camera3_jpeg_blob_t 859 //Append at the end of jpeg image of buf_filled_len size 860 861 jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID; 862 jpegHeader.jpeg_size = p_output->buf_filled_len; 863 864 865 char* jpeg_buf = (char *)p_output->buf_vaddr; 866 867 if(obj->mJpegSettings->max_jpeg_size <= 0 || 868 obj->mJpegSettings->max_jpeg_size > obj->mMemory->getSize(obj->mCurrentBufIndex)){ 869 ALOGE("%s:Max Jpeg size :%d is out of valid range setting to size of buffer", 870 __func__, obj->mJpegSettings->max_jpeg_size); 871 maxJpegSize = obj->mMemory->getSize(obj->mCurrentBufIndex); 872 } else { 873 maxJpegSize = obj->mJpegSettings->max_jpeg_size; 874 ALOGE("%s: Setting max jpeg size to %d",__func__, maxJpegSize); 875 } 876 jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)]; 877 memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader)); 878 obj->mMemory->cleanInvalidateCache(obj->mCurrentBufIndex); 879 880 ////Use below data to issue framework callback 881 resultBuffer = obj->mCamera3Buffers[obj->mCurrentBufIndex]; 882 resultFrameNumber = obj->mMemory->getFrameNumber(obj->mCurrentBufIndex); 883 884 result.stream = obj->mCamera3Stream; 885 result.buffer = resultBuffer; 886 result.status = resultStatus; 887 result.acquire_fence = -1; 888 result.release_fence = -1; 889 890 ALOGV("%s: Issue Callback", __func__); 891 obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData); 892 893 // release internal data for jpeg job 894 if (job != NULL) { 895 obj->m_postprocessor.releaseJpegJobData(job); 896 free(job); 897 } 898 return; 899 // } 900 } else { 901 ALOGE("%s: Null userdata in jpeg callback", __func__); 902 } 903 } 904 905 QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle, 906 mm_camera_ops_t *cam_ops, 907 channel_cb_routine cb_routine, 908 cam_padding_info_t *paddingInfo, 909 void *userData, 910 camera3_stream_t *stream) : 911 QCamera3Channel(cam_handle, cam_ops, cb_routine, 912 paddingInfo, userData), 913 m_postprocessor(this), 914 mCamera3Stream(stream), 915 mNumBufs(0), 916 mCamera3Buffers(NULL), 917 mJpegSettings(NULL), 918 mCurrentBufIndex(-1), 919 mMemory(NULL), 920 mYuvMemory(NULL) 921 { 922 int32_t rc = m_postprocessor.init(jpegEvtHandle, this); 923 if (rc != 0) { 924 ALOGE("Init Postprocessor failed"); 925 } 926 } 927 928 QCamera3PicChannel::~QCamera3PicChannel() 929 { 930 int32_t rc = m_postprocessor.stop(); 931 if (rc != NO_ERROR) { 932 ALOGE("%s: Postprocessor stop failed", __func__); 933 } 934 rc = m_postprocessor.deinit(); 935 if (rc != 0) { 936 ALOGE("De-init Postprocessor failed"); 937 } 938 if (mCamera3Buffers) { 939 delete[] mCamera3Buffers; 940 } 941 } 942 943 int32_t QCamera3PicChannel::initialize() 944 { 945 int32_t rc = NO_ERROR; 946 cam_dimension_t streamDim; 947 cam_stream_type_t streamType; 948 cam_format_t streamFormat; 949 mm_camera_channel_attr_t attr; 950 951 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 952 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 953 attr.look_back = 1; 954 attr.post_frame_skip = 1; 955 attr.water_mark = 1; 956 attr.max_unmatched_frames = 1; 957 958 rc = init(&attr, NULL); 959 if (rc < 0) { 960 ALOGE("%s: init failed", __func__); 961 return rc; 962 } 963 964 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 965 streamFormat = CAM_FORMAT_YUV_420_NV21; 966 streamDim.width = mCamera3Stream->width; 967 streamDim.height = mCamera3Stream->height; 968 969 int num_buffers = 1; 970 971 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 972 num_buffers); 973 974 return rc; 975 } 976 977 int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, 978 uint32_t frameNumber, jpeg_settings_t* jpegSettings, 979 mm_camera_buf_def_t *pInputBuffer,QCamera3Channel* pInputChannel) 980 { 981 //FIX ME: Return buffer back in case of failures below. 982 983 int32_t rc = NO_ERROR; 984 int index; 985 mJpegSettings = jpegSettings; 986 if(!m_bIsActive) { 987 ALOGD("%s: First request on this channel starting stream",__func__); 988 //Stream on for main image. YUV buffer is queued to the kernel at the end of this call. 989 if(!pInputBuffer) 990 rc = start(); 991 else 992 ALOGD("%s: Current request has input buffer no need to start h/w stream", __func__); 993 } else { 994 mStreams[0]->bufDone(0); 995 ALOGD("%s: Request on an existing stream",__func__); 996 } 997 998 if(rc != NO_ERROR) { 999 ALOGE("%s: Failed to start the stream on the request",__func__); 1000 return rc; 1001 } 1002 1003 1004 if(!mMemory) { 1005 if(pInputBuffer) { 1006 mMemory = new QCamera3GrallocMemory(); 1007 if (mMemory == NULL) { 1008 return NO_MEMORY; 1009 } 1010 1011 //Registering Jpeg output buffer 1012 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1013 delete mMemory; 1014 mMemory = NULL; 1015 return NO_MEMORY; 1016 } 1017 } else { 1018 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 1019 return NO_MEMORY; 1020 } 1021 } 1022 1023 index = mMemory->getMatchBufIndex((void*)buffer); 1024 if(index < 0) { 1025 ALOGE("%s: Could not find object among registered buffers",__func__); 1026 return DEAD_OBJECT; 1027 } 1028 rc = mMemory->markFrameNumber(index, frameNumber); 1029 1030 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer 1031 mCurrentBufIndex = index; 1032 1033 m_postprocessor.start(mMemory, index, this); 1034 1035 ALOGD("%s: Post-process started", __func__); 1036 if(pInputBuffer) { 1037 ALOGD("%s: Issue call to reprocess", __func__); 1038 m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel); 1039 } 1040 return rc; 1041 } 1042 1043 /*=========================================================================== 1044 * FUNCTION : dataNotifyCB 1045 * 1046 * DESCRIPTION: Channel Level callback used for super buffer data notify. 1047 * This function is registered with mm-camera-interface to handle 1048 * data notify 1049 * 1050 * PARAMETERS : 1051 * @recvd_frame : stream frame received 1052 * userdata : user data ptr 1053 * 1054 * RETURN : none 1055 *==========================================================================*/ 1056 void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1057 void *userdata) 1058 { 1059 ALOGV("%s: E\n", __func__); 1060 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 1061 1062 if (channel == NULL) { 1063 ALOGE("%s: invalid channel pointer", __func__); 1064 return; 1065 } 1066 1067 if(channel->m_numStreams != 1) { 1068 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 1069 return; 1070 } 1071 1072 1073 if(channel->mStreams[0] == NULL) { 1074 ALOGE("%s: Error: Invalid Stream object",__func__); 1075 return; 1076 } 1077 1078 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 1079 1080 ALOGV("%s: X\n", __func__); 1081 return; 1082 } 1083 1084 1085 int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 1086 buffer_handle_t **buffers) 1087 { 1088 int rc = 0; 1089 cam_stream_type_t streamType; 1090 cam_format_t streamFormat; 1091 1092 ALOGV("%s: E",__func__); 1093 rc = QCamera3PicChannel::initialize(); 1094 if (rc < 0) { 1095 ALOGE("%s: init failed", __func__); 1096 return rc; 1097 } 1098 1099 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 1100 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 1101 streamFormat = CAM_FORMAT_YUV_420_NV21; 1102 } else { 1103 //TODO: Fail for other types of streams for now 1104 ALOGE("%s: format is not BLOB", __func__); 1105 return -EINVAL; 1106 } 1107 /* Bookkeep buffer set because they go out of scope after register call */ 1108 mNumBufs = num_buffers; 1109 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 1110 if (mCamera3Buffers == NULL) { 1111 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 1112 return -ENOMEM; 1113 } 1114 for (size_t i = 0; i < num_buffers; i++) 1115 mCamera3Buffers[i] = buffers[i]; 1116 1117 ALOGV("%s: X",__func__); 1118 return rc; 1119 } 1120 1121 void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1122 QCamera3Stream *stream) 1123 { 1124 //TODO 1125 //Used only for getting YUV. Jpeg callback will be sent back from channel 1126 //directly to HWI. Refer to func jpegEvtHandle 1127 1128 //Got the yuv callback. Calling yuv callback handler in PostProc 1129 uint8_t frameIndex; 1130 mm_camera_super_buf_t* frame = NULL; 1131 if(!super_frame) { 1132 ALOGE("%s: Invalid Super buffer",__func__); 1133 return; 1134 } 1135 1136 if(super_frame->num_bufs != 1) { 1137 ALOGE("%s: Multiple streams are not supported",__func__); 1138 return; 1139 } 1140 if(super_frame->bufs[0] == NULL ) { 1141 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1142 __func__); 1143 return; 1144 } 1145 1146 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1147 if(frameIndex >= mNumBufs) { 1148 ALOGE("%s: Error, Invalid index for buffer",__func__); 1149 if(stream) { 1150 stream->bufDone(frameIndex); 1151 } 1152 return; 1153 } 1154 1155 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1156 if (frame == NULL) { 1157 ALOGE("%s: Error allocating memory to save received_frame structure.", 1158 __func__); 1159 if(stream) { 1160 stream->bufDone(frameIndex); 1161 } 1162 return; 1163 } 1164 *frame = *super_frame; 1165 1166 m_postprocessor.processData(frame); 1167 free(super_frame); 1168 return; 1169 } 1170 1171 QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1172 { 1173 int rc = 0; 1174 1175 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1176 ALOGE("%s: buffers not registered yet", __func__); 1177 return NULL; 1178 } 1179 1180 if(mMemory) { 1181 delete mMemory; 1182 mMemory = NULL; 1183 } 1184 mMemory = new QCamera3GrallocMemory(); 1185 if (mMemory == NULL) { 1186 return NULL; 1187 } 1188 1189 //Registering Jpeg output buffer 1190 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1191 delete mMemory; 1192 mMemory = NULL; 1193 return NULL; 1194 } 1195 1196 mYuvMemory = new QCamera3HeapMemory(); 1197 if (!mYuvMemory) { 1198 ALOGE("%s: unable to create metadata memory", __func__); 1199 return NULL; 1200 } 1201 1202 //Queue YUV buffers in the beginning mQueueAll = true 1203 rc = mYuvMemory->allocate(1, len, true); 1204 if (rc < 0) { 1205 ALOGE("%s: unable to allocate metadata memory", __func__); 1206 delete mYuvMemory; 1207 mYuvMemory = NULL; 1208 return NULL; 1209 } 1210 return mYuvMemory; 1211 } 1212 1213 void QCamera3PicChannel::putStreamBufs() 1214 { 1215 mMemory->unregisterBuffers(); 1216 delete mMemory; 1217 mMemory = NULL; 1218 1219 mYuvMemory->deallocate(); 1220 delete mYuvMemory; 1221 mYuvMemory = NULL; 1222 } 1223 1224 bool QCamera3PicChannel::isRawSnapshot() 1225 { 1226 return !(mJpegSettings->is_jpeg_format); 1227 } 1228 /*=========================================================================== 1229 * FUNCTION : getThumbnailSize 1230 * 1231 * DESCRIPTION: get user set thumbnail size 1232 * 1233 * PARAMETERS : 1234 * @dim : output of thumbnail dimension 1235 * 1236 * RETURN : none 1237 *==========================================================================*/ 1238 void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1239 { 1240 dim = mJpegSettings->thumbnail_size; 1241 } 1242 1243 /*=========================================================================== 1244 * FUNCTION : getJpegQuality 1245 * 1246 * DESCRIPTION: get user set jpeg quality 1247 * 1248 * PARAMETERS : none 1249 * 1250 * RETURN : jpeg quality setting 1251 *==========================================================================*/ 1252 int QCamera3PicChannel::getJpegQuality() 1253 { 1254 int quality = mJpegSettings->jpeg_quality; 1255 if (quality < 0) { 1256 quality = 85; //set to default quality value 1257 } 1258 return quality; 1259 } 1260 1261 /*=========================================================================== 1262 * FUNCTION : getJpegRotation 1263 * 1264 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1265 * 1266 * PARAMETERS : none 1267 * 1268 * RETURN : rotation information 1269 *==========================================================================*/ 1270 int QCamera3PicChannel::getJpegRotation() { 1271 int rotation = mJpegSettings->jpeg_orientation; 1272 if (rotation < 0) { 1273 rotation = 0; 1274 } 1275 return rotation; 1276 } 1277 1278 void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf) 1279 { 1280 m_postprocessor.processPPMetadata(metadata_buf); 1281 } 1282 /*=========================================================================== 1283 * FUNCTION : getRational 1284 * 1285 * DESCRIPTION: compose rational struct 1286 * 1287 * PARAMETERS : 1288 * @rat : ptr to struct to store rational info 1289 * @num :num of the rational 1290 * @denom : denom of the rational 1291 * 1292 * RETURN : int32_t type of status 1293 * NO_ERROR -- success 1294 * none-zero failure code 1295 *==========================================================================*/ 1296 int32_t getRational(rat_t *rat, int num, int denom) 1297 { 1298 if (NULL == rat) { 1299 ALOGE("%s: NULL rat input", __func__); 1300 return BAD_VALUE; 1301 } 1302 rat->num = num; 1303 rat->denom = denom; 1304 return NO_ERROR; 1305 } 1306 1307 /*=========================================================================== 1308 * FUNCTION : getRational 1309 * 1310 * DESCRIPTION: compose rational struct 1311 * 1312 * PARAMETERS : 1313 * @rat : ptr to struct to store rational info 1314 * @num :num of the rational 1315 * @denom : denom of the rational 1316 * 1317 * RETURN : int32_t type of status 1318 * NO_ERROR -- success 1319 * none-zero failure code 1320 *==========================================================================*/ 1321 int32_t getRationalExposureTime(rat_t *rat, double num, double denom) 1322 { 1323 if (NULL == rat) { 1324 ALOGE("%s: NULL rat input", __func__); 1325 return BAD_VALUE; 1326 } 1327 rat->num = num; 1328 rat->denom = round(1.0 / denom); 1329 return NO_ERROR; 1330 } 1331 1332 /*=========================================================================== 1333 * FUNCTION : parseGPSCoordinate 1334 * 1335 * DESCRIPTION: parse GPS coordinate string 1336 * 1337 * PARAMETERS : 1338 * @coord_str : [input] coordinate string 1339 * @coord : [output] ptr to struct to store coordinate 1340 * 1341 * RETURN : int32_t type of status 1342 * NO_ERROR -- success 1343 * none-zero failure code 1344 *==========================================================================*/ 1345 int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1346 { 1347 if(coord == NULL) { 1348 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1349 return BAD_VALUE; 1350 } 1351 float degF = atof(coord_str); 1352 if (degF < 0) { 1353 degF = -degF; 1354 } 1355 float minF = (degF - (int) degF) * 60; 1356 float secF = (minF - (int) minF) * 60; 1357 1358 getRational(&coord[0], (int)degF, 1); 1359 getRational(&coord[1], (int)minF, 1); 1360 getRational(&coord[2], (int)(secF * 10000), 10000); 1361 return NO_ERROR; 1362 } 1363 1364 /*=========================================================================== 1365 * FUNCTION : getExifDateTime 1366 * 1367 * DESCRIPTION: query exif date time 1368 * 1369 * PARAMETERS : 1370 * @dateTime : string to store exif date time 1371 * @count : lenght of the dateTime string 1372 * 1373 * RETURN : int32_t type of status 1374 * NO_ERROR -- success 1375 * none-zero failure code 1376 *==========================================================================*/ 1377 int32_t getExifDateTime(char *dateTime, uint32_t &count) 1378 { 1379 //get time and date from system 1380 time_t rawtime; 1381 struct tm * timeinfo; 1382 time(&rawtime); 1383 timeinfo = localtime (&rawtime); 1384 //Write datetime according to EXIF Spec 1385 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1386 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1387 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1388 timeinfo->tm_mday, timeinfo->tm_hour, 1389 timeinfo->tm_min, timeinfo->tm_sec); 1390 count = 20; 1391 1392 return NO_ERROR; 1393 } 1394 1395 /*=========================================================================== 1396 * FUNCTION : getExifFocalLength 1397 * 1398 * DESCRIPTION: get exif focal lenght 1399 * 1400 * PARAMETERS : 1401 * @focalLength : ptr to rational strcut to store focal lenght 1402 * 1403 * RETURN : int32_t type of status 1404 * NO_ERROR -- success 1405 * none-zero failure code 1406 *==========================================================================*/ 1407 int32_t getExifFocalLength(rat_t *focalLength, float value) 1408 { 1409 int focalLengthValue = 1410 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1411 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1412 } 1413 1414 /*=========================================================================== 1415 * FUNCTION : getExifExpTimeInfo 1416 * 1417 * DESCRIPTION: get exif exposure time information 1418 * 1419 * PARAMETERS : 1420 * @expoTimeInfo : expousure time value 1421 * RETURN : nt32_t type of status 1422 * NO_ERROR -- success 1423 * none-zero failure code 1424 *==========================================================================*/ 1425 int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value) 1426 { 1427 1428 float cal_exposureTime; 1429 if (value != 0) 1430 cal_exposureTime = (double)(value / 1000000000.0); 1431 else 1432 cal_exposureTime = 60.00; 1433 return getRationalExposureTime(expoTimeInfo, 1, cal_exposureTime); 1434 } 1435 1436 /*=========================================================================== 1437 * FUNCTION : getExifGpsProcessingMethod 1438 * 1439 * DESCRIPTION: get GPS processing method 1440 * 1441 * PARAMETERS : 1442 * @gpsProcessingMethod : string to store GPS process method 1443 * @count : lenght of the string 1444 * 1445 * RETURN : int32_t type of status 1446 * NO_ERROR -- success 1447 * none-zero failure code 1448 *==========================================================================*/ 1449 int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1450 uint32_t &count, char* value) 1451 { 1452 if(value != NULL) { 1453 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1454 count = EXIF_ASCII_PREFIX_SIZE; 1455 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1456 count += strlen(value); 1457 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1458 return NO_ERROR; 1459 } else { 1460 return BAD_VALUE; 1461 } 1462 } 1463 1464 /*=========================================================================== 1465 * FUNCTION : getExifLatitude 1466 * 1467 * DESCRIPTION: get exif latitude 1468 * 1469 * PARAMETERS : 1470 * @latitude : ptr to rational struct to store latitude info 1471 * @ladRef : charater to indicate latitude reference 1472 * 1473 * RETURN : int32_t type of status 1474 * NO_ERROR -- success 1475 * none-zero failure code 1476 *==========================================================================*/ 1477 int32_t getExifLatitude(rat_t *latitude, 1478 char *latRef, double value) 1479 { 1480 char str[30]; 1481 snprintf(str, sizeof(str), "%f", value); 1482 if(str != NULL) { 1483 parseGPSCoordinate(str, latitude); 1484 1485 //set Latitude Ref 1486 float latitudeValue = strtof(str, 0); 1487 if(latitudeValue < 0.0f) { 1488 latRef[0] = 'S'; 1489 } else { 1490 latRef[0] = 'N'; 1491 } 1492 latRef[1] = '\0'; 1493 return NO_ERROR; 1494 }else{ 1495 return BAD_VALUE; 1496 } 1497 } 1498 1499 /*=========================================================================== 1500 * FUNCTION : getExifLongitude 1501 * 1502 * DESCRIPTION: get exif longitude 1503 * 1504 * PARAMETERS : 1505 * @longitude : ptr to rational struct to store longitude info 1506 * @lonRef : charater to indicate longitude reference 1507 * 1508 * RETURN : int32_t type of status 1509 * NO_ERROR -- success 1510 * none-zero failure code 1511 *==========================================================================*/ 1512 int32_t getExifLongitude(rat_t *longitude, 1513 char *lonRef, double value) 1514 { 1515 char str[30]; 1516 snprintf(str, sizeof(str), "%f", value); 1517 if(str != NULL) { 1518 parseGPSCoordinate(str, longitude); 1519 1520 //set Longitude Ref 1521 float longitudeValue = strtof(str, 0); 1522 if(longitudeValue < 0.0f) { 1523 lonRef[0] = 'W'; 1524 } else { 1525 lonRef[0] = 'E'; 1526 } 1527 lonRef[1] = '\0'; 1528 return NO_ERROR; 1529 }else{ 1530 return BAD_VALUE; 1531 } 1532 } 1533 1534 /*=========================================================================== 1535 * FUNCTION : getExifAltitude 1536 * 1537 * DESCRIPTION: get exif altitude 1538 * 1539 * PARAMETERS : 1540 * @altitude : ptr to rational struct to store altitude info 1541 * @altRef : charater to indicate altitude reference 1542 * 1543 * RETURN : int32_t type of status 1544 * NO_ERROR -- success 1545 * none-zero failure code 1546 *==========================================================================*/ 1547 int32_t getExifAltitude(rat_t *altitude, 1548 char *altRef, double value) 1549 { 1550 char str[30]; 1551 snprintf(str, sizeof(str), "%f", value); 1552 if(str != NULL) { 1553 double value = atof(str); 1554 *altRef = 0; 1555 if(value < 0){ 1556 *altRef = 1; 1557 value = -value; 1558 } 1559 return getRational(altitude, value*1000, 1000); 1560 }else{ 1561 return BAD_VALUE; 1562 } 1563 } 1564 1565 /*=========================================================================== 1566 * FUNCTION : getExifGpsDateTimeStamp 1567 * 1568 * DESCRIPTION: get exif GPS date time stamp 1569 * 1570 * PARAMETERS : 1571 * @gpsDateStamp : GPS date time stamp string 1572 * @bufLen : length of the string 1573 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1574 * 1575 * RETURN : int32_t type of status 1576 * NO_ERROR -- success 1577 * none-zero failure code 1578 *==========================================================================*/ 1579 int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1580 uint32_t bufLen, 1581 rat_t *gpsTimeStamp, int64_t value) 1582 { 1583 char str[30]; 1584 snprintf(str, sizeof(str), "%lld", value); 1585 if(str != NULL) { 1586 time_t unixTime = (time_t)atol(str); 1587 struct tm *UTCTimestamp = gmtime(&unixTime); 1588 1589 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1590 1591 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1592 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1593 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1594 1595 return NO_ERROR; 1596 } else { 1597 return BAD_VALUE; 1598 } 1599 } 1600 1601 int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1602 cam_rational_type_t step) 1603 { 1604 exposure_val->num = exposure_comp * step.numerator; 1605 exposure_val->denom = step.denominator; 1606 return 0; 1607 } 1608 /*=========================================================================== 1609 * FUNCTION : getExifData 1610 * 1611 * DESCRIPTION: get exif data to be passed into jpeg encoding 1612 * 1613 * PARAMETERS : none 1614 * 1615 * RETURN : exif data from user setting and GPS 1616 *==========================================================================*/ 1617 QCamera3Exif *QCamera3PicChannel::getExifData() 1618 { 1619 QCamera3Exif *exif = new QCamera3Exif(); 1620 if (exif == NULL) { 1621 ALOGE("%s: No memory for QCamera3Exif", __func__); 1622 return NULL; 1623 } 1624 1625 int32_t rc = NO_ERROR; 1626 uint32_t count = 0; 1627 1628 // add exif entries 1629 char dateTime[20]; 1630 memset(dateTime, 0, sizeof(dateTime)); 1631 count = 20; 1632 rc = getExifDateTime(dateTime, count); 1633 if(rc == NO_ERROR) { 1634 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1635 EXIF_ASCII, 1636 count, 1637 (void *)dateTime); 1638 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, 1639 EXIF_ASCII, 1640 count, 1641 (void *)dateTime); 1642 } else { 1643 ALOGE("%s: getExifDateTime failed", __func__); 1644 } 1645 1646 rat_t focalLength; 1647 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1648 if (rc == NO_ERROR) { 1649 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1650 EXIF_RATIONAL, 1651 1, 1652 (void *)&(focalLength)); 1653 } else { 1654 ALOGE("%s: getExifFocalLength failed", __func__); 1655 } 1656 1657 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity; 1658 if(isoSpeed == 0) { 1659 isoSpeed = (uint16_t)(mJpegSettings->lens_focal_length + 0.5)*100; 1660 } 1661 1662 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1663 EXIF_SHORT, 1664 1, 1665 (void *)&(isoSpeed)); 1666 1667 rat_t sensorExpTime, temp; 1668 rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time); 1669 if(sensorExpTime.denom <= 0) {// avoid zero-divide problem 1670 sensorExpTime.denom = 0.01668; // expoure time will be 1/60 s 1671 uint16_t temp2 = (uint16_t)(sensorExpTime.denom <= 0 * 100000); 1672 temp2 = (uint16_t)(100000 / temp2); 1673 temp.num = 1; 1674 temp.denom = temp2; 1675 memcpy(&sensorExpTime, &temp, sizeof(sensorExpTime)); 1676 } 1677 exif->addEntry(EXIFTAGID_EXPOSURE_TIME, 1678 EXIF_LONG, 1679 1, 1680 (void *) &(sensorExpTime.denom)); 1681 1682 if (strlen(mJpegSettings->gps_processing_method) > 0) { 1683 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1684 count = 0; 1685 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1686 if(rc == NO_ERROR) { 1687 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1688 EXIF_ASCII, 1689 count, 1690 (void *)gpsProcessingMethod); 1691 } else { 1692 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1693 } 1694 } 1695 1696 if (mJpegSettings->gps_coordinates[0]) { 1697 rat_t latitude[3]; 1698 char latRef[2]; 1699 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0])); 1700 if(rc == NO_ERROR) { 1701 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1702 EXIF_RATIONAL, 1703 3, 1704 (void *)latitude); 1705 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1706 EXIF_ASCII, 1707 2, 1708 (void *)latRef); 1709 } else { 1710 ALOGE("%s: getExifLatitude failed", __func__); 1711 } 1712 } 1713 1714 if (mJpegSettings->gps_coordinates[1]) { 1715 rat_t longitude[3]; 1716 char lonRef[2]; 1717 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1])); 1718 if(rc == NO_ERROR) { 1719 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1720 EXIF_RATIONAL, 1721 3, 1722 (void *)longitude); 1723 1724 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1725 EXIF_ASCII, 1726 2, 1727 (void *)lonRef); 1728 } else { 1729 ALOGE("%s: getExifLongitude failed", __func__); 1730 } 1731 } 1732 1733 if (mJpegSettings->gps_coordinates[2]) { 1734 rat_t altitude; 1735 char altRef; 1736 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2])); 1737 if(rc == NO_ERROR) { 1738 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1739 EXIF_RATIONAL, 1740 1, 1741 (void *)&(altitude)); 1742 1743 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1744 EXIF_BYTE, 1745 1, 1746 (void *)&altRef); 1747 } else { 1748 ALOGE("%s: getExifAltitude failed", __func__); 1749 } 1750 } 1751 1752 if (mJpegSettings->gps_timestamp) { 1753 char gpsDateStamp[20]; 1754 rat_t gpsTimeStamp[3]; 1755 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp)); 1756 if(rc == NO_ERROR) { 1757 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1758 EXIF_ASCII, 1759 strlen(gpsDateStamp) + 1, 1760 (void *)gpsDateStamp); 1761 1762 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1763 EXIF_RATIONAL, 1764 3, 1765 (void *)gpsTimeStamp); 1766 } else { 1767 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1768 } 1769 } 1770 1771 srat_t exposure_val; 1772 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation, 1773 mJpegSettings->exposure_comp_step); 1774 if(rc == NO_ERROR) { 1775 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1776 EXIF_SRATIONAL, 1777 1, 1778 (void *)(&exposure_val)); 1779 } else { 1780 ALOGE("%s: getExifExposureValue failed ", __func__); 1781 } 1782 1783 char value[PROPERTY_VALUE_MAX]; 1784 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 1785 exif->addEntry(EXIFTAGID_MAKE, 1786 EXIF_ASCII, 1787 strlen(value) + 1, 1788 (void *)value); 1789 } else { 1790 ALOGE("%s: getExifMaker failed", __func__); 1791 } 1792 1793 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 1794 exif->addEntry(EXIFTAGID_MODEL, 1795 EXIF_ASCII, 1796 strlen(value) + 1, 1797 (void *)value); 1798 } else { 1799 ALOGE("%s: getExifModel failed", __func__); 1800 } 1801 1802 float f_number = 0.0f; 1803 f_number = mJpegSettings->f_number; 1804 rat_t aperture; 1805 getRational(&aperture, (uint32_t)f_number*F_NUMBER_DECIMAL_PRECISION, (uint32_t)F_NUMBER_DECIMAL_PRECISION); 1806 exif->addEntry(EXIFTAGID_APERTURE, 1807 EXIF_RATIONAL, 1808 1, 1809 (void *)&(aperture)); 1810 1811 exif->addEntry(EXIFTAGID_F_NUMBER, 1812 EXIF_RATIONAL, 1813 1, 1814 (void *)&(aperture)); 1815 1816 uint16_t flash = mJpegSettings->flash; 1817 exif->addEntry(EXIFTAGID_FLASH, 1818 EXIF_SHORT, 1, 1819 (void *)&(flash)); 1820 1821 int wb; 1822 short val_short; 1823 wb = mJpegSettings->wb; 1824 if(wb == CAM_WB_MODE_AUTO) 1825 val_short = 0; 1826 else 1827 val_short = 1; 1828 1829 exif->addEntry(EXIFTAGID_WHITE_BALANCE, 1830 EXIF_SHORT, 1831 1, 1832 (void *)&(wb)); 1833 1834 struct timeval tv; 1835 char subsecTime[7]; 1836 gettimeofday(&tv, NULL); 1837 snprintf(subsecTime, 7, "%06ld", tv.tv_usec); 1838 1839 exif->addEntry(EXIFTAGID_SUBSEC_TIME, 1840 EXIF_ASCII, 7, 1841 (void *)subsecTime); 1842 1843 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, 1844 EXIF_ASCII, 7, 1845 (void *)subsecTime); 1846 1847 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, 1848 EXIF_ASCII, 7, 1849 (void *)subsecTime); 1850 1851 return exif; 1852 } 1853 1854 int QCamera3PicChannel::kMaxBuffers = 2; 1855 1856 /*=========================================================================== 1857 * FUNCTION : QCamera3ReprocessChannel 1858 * 1859 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1860 * 1861 * PARAMETERS : 1862 * @cam_handle : camera handle 1863 * @cam_ops : ptr to camera ops table 1864 * @pp_mask : post-proccess feature mask 1865 * 1866 * RETURN : none 1867 *==========================================================================*/ 1868 QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle, 1869 mm_camera_ops_t *cam_ops, 1870 channel_cb_routine cb_routine, 1871 cam_padding_info_t *paddingInfo, 1872 void *userData, void *ch_hdl) : 1873 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData), 1874 picChHandle(ch_hdl), 1875 m_pSrcChannel(NULL), 1876 m_pMetaChannel(NULL), 1877 m_metaFrame(NULL), 1878 mMemory(NULL) 1879 { 1880 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 1881 } 1882 1883 1884 /*=========================================================================== 1885 * FUNCTION : QCamera3ReprocessChannel 1886 * 1887 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1888 * 1889 * PARAMETERS : 1890 * @cam_handle : camera handle 1891 * @cam_ops : ptr to camera ops table 1892 * @pp_mask : post-proccess feature mask 1893 * 1894 * RETURN : none 1895 *==========================================================================*/ 1896 int32_t QCamera3ReprocessChannel::initialize() 1897 { 1898 int32_t rc = NO_ERROR; 1899 mm_camera_channel_attr_t attr; 1900 1901 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 1902 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 1903 attr.max_unmatched_frames = 1; 1904 1905 rc = init(&attr, NULL); 1906 if (rc < 0) { 1907 ALOGE("%s: init failed", __func__); 1908 } 1909 return rc; 1910 } 1911 1912 1913 /*=========================================================================== 1914 * FUNCTION : QCamera3ReprocessChannel 1915 * 1916 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1917 * 1918 * PARAMETERS : 1919 * @cam_handle : camera handle 1920 * @cam_ops : ptr to camera ops table 1921 * @pp_mask : post-proccess feature mask 1922 * 1923 * RETURN : none 1924 *==========================================================================*/ 1925 void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1926 QCamera3Stream *stream) 1927 { 1928 //Got the pproc data callback. Now send to jpeg encoding 1929 uint8_t frameIndex; 1930 mm_camera_super_buf_t* frame = NULL; 1931 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle; 1932 1933 if(!super_frame) { 1934 ALOGE("%s: Invalid Super buffer",__func__); 1935 return; 1936 } 1937 1938 if(super_frame->num_bufs != 1) { 1939 ALOGE("%s: Multiple streams are not supported",__func__); 1940 return; 1941 } 1942 if(super_frame->bufs[0] == NULL ) { 1943 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1944 __func__); 1945 return; 1946 } 1947 1948 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1949 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1950 if (frame == NULL) { 1951 ALOGE("%s: Error allocating memory to save received_frame structure.", 1952 __func__); 1953 if(stream) { 1954 stream->bufDone(frameIndex); 1955 } 1956 return; 1957 } 1958 *frame = *super_frame; 1959 //queue back the metadata buffer 1960 if (m_metaFrame != NULL) { 1961 ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(m_metaFrame); 1962 free(m_metaFrame); 1963 m_metaFrame = NULL; 1964 } else { 1965 ALOGE("%s: Meta frame was NULL", __func__); 1966 } 1967 obj->m_postprocessor.processPPData(frame); 1968 return; 1969 } 1970 1971 /*=========================================================================== 1972 * FUNCTION : QCamera3ReprocessChannel 1973 * 1974 * DESCRIPTION: default constructor of QCamera3ReprocessChannel 1975 * 1976 * PARAMETERS : none 1977 * 1978 * RETURN : none 1979 *==========================================================================*/ 1980 QCamera3ReprocessChannel::QCamera3ReprocessChannel() : 1981 m_pSrcChannel(NULL), 1982 m_pMetaChannel(NULL), 1983 m_metaFrame(NULL) 1984 { 1985 } 1986 1987 /*=========================================================================== 1988 * FUNCTION : QCamera3ReprocessChannel 1989 * 1990 * DESCRIPTION: register the buffers of the reprocess channel 1991 * 1992 * PARAMETERS : none 1993 * 1994 * RETURN : none 1995 *==========================================================================*/ 1996 int32_t QCamera3ReprocessChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 1997 { 1998 return 0; 1999 } 2000 2001 /*=========================================================================== 2002 * FUNCTION : getStreamBufs 2003 * 2004 * DESCRIPTION: register the buffers of the reprocess channel 2005 * 2006 * PARAMETERS : none 2007 * 2008 * RETURN : QCamera3Memory * 2009 *==========================================================================*/ 2010 QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len) 2011 { 2012 int rc = 0; 2013 2014 mMemory = new QCamera3HeapMemory(); 2015 if (!mMemory) { 2016 ALOGE("%s: unable to create reproc memory", __func__); 2017 return NULL; 2018 } 2019 2020 //Queue YUV buffers in the beginning mQueueAll = true 2021 rc = mMemory->allocate(2, len, true); 2022 if (rc < 0) { 2023 ALOGE("%s: unable to allocate reproc memory", __func__); 2024 delete mMemory; 2025 mMemory = NULL; 2026 return NULL; 2027 } 2028 return mMemory; 2029 } 2030 2031 /*=========================================================================== 2032 * FUNCTION : getStreamBufs 2033 * 2034 * DESCRIPTION: register the buffers of the reprocess channel 2035 * 2036 * PARAMETERS : none 2037 * 2038 * RETURN : 2039 *==========================================================================*/ 2040 void QCamera3ReprocessChannel::putStreamBufs() 2041 { 2042 mMemory->deallocate(); 2043 delete mMemory; 2044 mMemory = NULL; 2045 } 2046 2047 /*=========================================================================== 2048 * FUNCTION : ~QCamera3ReprocessChannel 2049 * 2050 * DESCRIPTION: destructor of QCamera3ReprocessChannel 2051 * 2052 * PARAMETERS : none 2053 * 2054 * RETURN : none 2055 *==========================================================================*/ 2056 QCamera3ReprocessChannel::~QCamera3ReprocessChannel() 2057 { 2058 } 2059 2060 /*=========================================================================== 2061 * FUNCTION : getStreamBySourceHandle 2062 * 2063 * DESCRIPTION: find reprocess stream by its source stream handle 2064 * 2065 * PARAMETERS : 2066 * @srcHandle : source stream handle 2067 * 2068 * RETURN : ptr to reprocess stream if found. NULL if not found 2069 *==========================================================================*/ 2070 QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle) 2071 { 2072 QCamera3Stream *pStream = NULL; 2073 2074 for (int i = 0; i < m_numStreams; i++) { 2075 if (mSrcStreamHandles[i] == srcHandle) { 2076 pStream = mStreams[i]; 2077 break; 2078 } 2079 } 2080 return pStream; 2081 } 2082 2083 /*=========================================================================== 2084 * FUNCTION : doReprocess 2085 * 2086 * DESCRIPTION: request to do a reprocess on the frame 2087 * 2088 * PARAMETERS : 2089 * @frame : frame to be performed a reprocess 2090 * 2091 * RETURN : int32_t type of status 2092 * NO_ERROR -- success 2093 * none-zero failure code 2094 *==========================================================================*/ 2095 int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 2096 mm_camera_super_buf_t *meta_frame) 2097 { 2098 int32_t rc = 0; 2099 if (m_numStreams < 1) { 2100 ALOGE("%s: No reprocess stream is created", __func__); 2101 return -1; 2102 } 2103 if (m_pSrcChannel == NULL) { 2104 ALOGE("%s: No source channel for reprocess", __func__); 2105 return -1; 2106 } 2107 m_metaFrame = meta_frame; 2108 for (int i = 0; i < frame->num_bufs; i++) { 2109 QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id); 2110 if (pStream != NULL) { 2111 cam_stream_parm_buffer_t param; 2112 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2113 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2114 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 2115 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 2116 if (meta_frame != NULL) { 2117 param.reprocess.meta_present = 1; 2118 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2119 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2120 } 2121 rc = pStream->setParameter(param); 2122 if (rc != NO_ERROR) { 2123 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2124 break; 2125 } 2126 } 2127 } 2128 return rc; 2129 } 2130 2131 /*=========================================================================== 2132 * FUNCTION : doReprocess 2133 * 2134 * DESCRIPTION: request to do a reprocess on the frame 2135 * 2136 * PARAMETERS : 2137 * @buf_fd : fd to the input buffer that needs reprocess 2138 * @buf_lenght : length of the input buffer 2139 * @ret_val : result of reprocess. 2140 * Example: Could be faceID in case of register face image. 2141 * 2142 * RETURN : int32_t type of status 2143 * NO_ERROR -- success 2144 * none-zero failure code 2145 *==========================================================================*/ 2146 int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd, 2147 uint32_t buf_length, 2148 int32_t &ret_val, 2149 mm_camera_super_buf_t *meta_frame) 2150 { 2151 int32_t rc = 0; 2152 if (m_numStreams < 1) { 2153 ALOGE("%s: No reprocess stream is created", __func__); 2154 return -1; 2155 } 2156 if (meta_frame == NULL) { 2157 ALOGE("%s: Did not get corresponding metadata in time", __func__); 2158 return -1; 2159 } 2160 2161 uint32_t buf_idx = 0; 2162 for (int i = 0; i < m_numStreams; i++) { 2163 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2164 buf_idx, -1, 2165 buf_fd, buf_length); 2166 2167 if (rc == NO_ERROR) { 2168 cam_stream_parm_buffer_t param; 2169 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2170 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2171 param.reprocess.buf_index = buf_idx; 2172 param.reprocess.meta_present = 1; 2173 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2174 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2175 rc = mStreams[i]->setParameter(param); 2176 if (rc == NO_ERROR) { 2177 ret_val = param.reprocess.ret_val; 2178 } 2179 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2180 buf_idx, -1); 2181 } 2182 } 2183 return rc; 2184 } 2185 2186 /*=========================================================================== 2187 * FUNCTION : addReprocStreamsFromSource 2188 * 2189 * DESCRIPTION: add reprocess streams from input source channel 2190 * 2191 * PARAMETERS : 2192 * @config : pp feature configuration 2193 * @pSrcChannel : ptr to input source channel that needs reprocess 2194 * @pMetaChannel : ptr to metadata channel to get corresp. metadata 2195 * 2196 * RETURN : int32_t type of status 2197 * NO_ERROR -- success 2198 * none-zero failure code 2199 *==========================================================================*/ 2200 int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config, 2201 QCamera3Channel *pSrcChannel, 2202 QCamera3Channel *pMetaChannel) 2203 { 2204 int32_t rc = 0; 2205 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0); 2206 if (pSrcStream == NULL) { 2207 ALOGE("%s: source channel doesn't have a stream", __func__); 2208 return BAD_VALUE; 2209 } 2210 cam_stream_reproc_config_t reprocess_config; 2211 cam_dimension_t streamDim; 2212 cam_stream_type_t streamType; 2213 cam_format_t streamFormat; 2214 cam_frame_len_offset_t frameOffset; 2215 int num_buffers = 2; 2216 2217 streamType = CAM_STREAM_TYPE_OFFLINE_PROC; 2218 pSrcStream->getFormat(streamFormat); 2219 pSrcStream->getFrameDimension(streamDim); 2220 pSrcStream->getFrameOffset(frameOffset); 2221 2222 reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE; 2223 reprocess_config.online.input_stream_id = pSrcStream->getMyServerID(); 2224 reprocess_config.online.input_stream_type = pSrcStream->getMyType(); 2225 reprocess_config.pp_feature_config = config; 2226 2227 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle(); 2228 2229 if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 2230 if (reprocess_config.pp_feature_config.rotation == ROTATE_90 || 2231 reprocess_config.pp_feature_config.rotation == ROTATE_270) { 2232 // rotated by 90 or 270, need to switch width and height 2233 int32_t temp = streamDim.height; 2234 streamDim.height = streamDim.width; 2235 streamDim.width = temp; 2236 } 2237 } 2238 2239 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 2240 m_handle, 2241 m_camOps, 2242 mPaddingInfo, 2243 (QCamera3Channel*)this); 2244 if (pStream == NULL) { 2245 ALOGE("%s: No mem for Stream", __func__); 2246 return NO_MEMORY; 2247 } 2248 2249 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config, 2250 num_buffers,QCamera3Channel::streamCbRoutine, this); 2251 2252 2253 if (rc == 0) { 2254 mStreams[m_numStreams] = pStream; 2255 m_numStreams++; 2256 } else { 2257 ALOGE("%s: failed to create reprocess stream", __func__); 2258 delete pStream; 2259 } 2260 2261 if (rc == NO_ERROR) { 2262 m_pSrcChannel = pSrcChannel; 2263 m_pMetaChannel = pMetaChannel; 2264 } 2265 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 2266 ALOGE("%s: Request for super buffer failed",__func__); 2267 } 2268 return rc; 2269 } 2270 2271 2272 }; // namespace qcamera 2273