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.deinit(); 931 if (rc != 0) { 932 ALOGE("De-init Postprocessor failed"); 933 } 934 if (mCamera3Buffers) { 935 delete[] mCamera3Buffers; 936 } 937 } 938 939 int32_t QCamera3PicChannel::initialize() 940 { 941 int32_t rc = NO_ERROR; 942 cam_dimension_t streamDim; 943 cam_stream_type_t streamType; 944 cam_format_t streamFormat; 945 mm_camera_channel_attr_t attr; 946 947 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 948 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 949 attr.look_back = 1; 950 attr.post_frame_skip = 1; 951 attr.water_mark = 1; 952 attr.max_unmatched_frames = 1; 953 954 rc = init(&attr, NULL); 955 if (rc < 0) { 956 ALOGE("%s: init failed", __func__); 957 return rc; 958 } 959 960 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 961 streamFormat = CAM_FORMAT_YUV_420_NV21; 962 streamDim.width = mCamera3Stream->width; 963 streamDim.height = mCamera3Stream->height; 964 965 int num_buffers = 1; 966 967 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 968 num_buffers); 969 970 return rc; 971 } 972 973 int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, 974 uint32_t frameNumber, jpeg_settings_t* jpegSettings, 975 mm_camera_buf_def_t *pInputBuffer,QCamera3Channel* pInputChannel) 976 { 977 //FIX ME: Return buffer back in case of failures below. 978 979 int32_t rc = NO_ERROR; 980 int index; 981 mJpegSettings = jpegSettings; 982 if(!m_bIsActive) { 983 ALOGD("%s: First request on this channel starting stream",__func__); 984 //Stream on for main image. YUV buffer is queued to the kernel at the end of this call. 985 if(!pInputBuffer) 986 rc = start(); 987 else 988 ALOGD("%s: Current request has input buffer no need to start h/w stream", __func__); 989 } else { 990 mStreams[0]->bufDone(0); 991 ALOGD("%s: Request on an existing stream",__func__); 992 } 993 994 if(rc != NO_ERROR) { 995 ALOGE("%s: Failed to start the stream on the request",__func__); 996 return rc; 997 } 998 999 1000 if(!mMemory) { 1001 if(pInputBuffer) { 1002 mMemory = new QCamera3GrallocMemory(); 1003 if (mMemory == NULL) { 1004 return NO_MEMORY; 1005 } 1006 1007 //Registering Jpeg output buffer 1008 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1009 delete mMemory; 1010 mMemory = NULL; 1011 return NO_MEMORY; 1012 } 1013 } else { 1014 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 1015 return NO_MEMORY; 1016 } 1017 } 1018 1019 index = mMemory->getMatchBufIndex((void*)buffer); 1020 if(index < 0) { 1021 ALOGE("%s: Could not find object among registered buffers",__func__); 1022 return DEAD_OBJECT; 1023 } 1024 rc = mMemory->markFrameNumber(index, frameNumber); 1025 1026 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer 1027 mCurrentBufIndex = index; 1028 1029 m_postprocessor.start(mMemory, index, this); 1030 1031 ALOGD("%s: Post-process started", __func__); 1032 if(pInputBuffer) { 1033 ALOGD("%s: Issue call to reprocess", __func__); 1034 m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel); 1035 } 1036 return rc; 1037 } 1038 1039 /*=========================================================================== 1040 * FUNCTION : dataNotifyCB 1041 * 1042 * DESCRIPTION: Channel Level callback used for super buffer data notify. 1043 * This function is registered with mm-camera-interface to handle 1044 * data notify 1045 * 1046 * PARAMETERS : 1047 * @recvd_frame : stream frame received 1048 * userdata : user data ptr 1049 * 1050 * RETURN : none 1051 *==========================================================================*/ 1052 void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1053 void *userdata) 1054 { 1055 ALOGV("%s: E\n", __func__); 1056 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 1057 1058 if (channel == NULL) { 1059 ALOGE("%s: invalid channel pointer", __func__); 1060 return; 1061 } 1062 1063 if(channel->m_numStreams != 1) { 1064 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 1065 return; 1066 } 1067 1068 1069 if(channel->mStreams[0] == NULL) { 1070 ALOGE("%s: Error: Invalid Stream object",__func__); 1071 return; 1072 } 1073 1074 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 1075 1076 ALOGV("%s: X\n", __func__); 1077 return; 1078 } 1079 1080 1081 int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 1082 buffer_handle_t **buffers) 1083 { 1084 int rc = 0; 1085 cam_stream_type_t streamType; 1086 cam_format_t streamFormat; 1087 1088 ALOGV("%s: E",__func__); 1089 rc = QCamera3PicChannel::initialize(); 1090 if (rc < 0) { 1091 ALOGE("%s: init failed", __func__); 1092 return rc; 1093 } 1094 1095 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 1096 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 1097 streamFormat = CAM_FORMAT_YUV_420_NV21; 1098 } else { 1099 //TODO: Fail for other types of streams for now 1100 ALOGE("%s: format is not BLOB", __func__); 1101 return -EINVAL; 1102 } 1103 /* Bookkeep buffer set because they go out of scope after register call */ 1104 mNumBufs = num_buffers; 1105 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 1106 if (mCamera3Buffers == NULL) { 1107 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 1108 return -ENOMEM; 1109 } 1110 for (size_t i = 0; i < num_buffers; i++) 1111 mCamera3Buffers[i] = buffers[i]; 1112 1113 ALOGV("%s: X",__func__); 1114 return rc; 1115 } 1116 1117 void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1118 QCamera3Stream *stream) 1119 { 1120 //TODO 1121 //Used only for getting YUV. Jpeg callback will be sent back from channel 1122 //directly to HWI. Refer to func jpegEvtHandle 1123 1124 //Got the yuv callback. Calling yuv callback handler in PostProc 1125 uint8_t frameIndex; 1126 mm_camera_super_buf_t* frame = NULL; 1127 if(!super_frame) { 1128 ALOGE("%s: Invalid Super buffer",__func__); 1129 return; 1130 } 1131 1132 if(super_frame->num_bufs != 1) { 1133 ALOGE("%s: Multiple streams are not supported",__func__); 1134 return; 1135 } 1136 if(super_frame->bufs[0] == NULL ) { 1137 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1138 __func__); 1139 return; 1140 } 1141 1142 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1143 if(frameIndex >= mNumBufs) { 1144 ALOGE("%s: Error, Invalid index for buffer",__func__); 1145 if(stream) { 1146 stream->bufDone(frameIndex); 1147 } 1148 return; 1149 } 1150 1151 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1152 if (frame == NULL) { 1153 ALOGE("%s: Error allocating memory to save received_frame structure.", 1154 __func__); 1155 if(stream) { 1156 stream->bufDone(frameIndex); 1157 } 1158 return; 1159 } 1160 *frame = *super_frame; 1161 1162 m_postprocessor.processData(frame); 1163 free(super_frame); 1164 return; 1165 } 1166 1167 QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1168 { 1169 int rc = 0; 1170 1171 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1172 ALOGE("%s: buffers not registered yet", __func__); 1173 return NULL; 1174 } 1175 1176 if(mMemory) { 1177 delete mMemory; 1178 mMemory = NULL; 1179 } 1180 mMemory = new QCamera3GrallocMemory(); 1181 if (mMemory == NULL) { 1182 return NULL; 1183 } 1184 1185 //Registering Jpeg output buffer 1186 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1187 delete mMemory; 1188 mMemory = NULL; 1189 return NULL; 1190 } 1191 1192 mYuvMemory = new QCamera3HeapMemory(); 1193 if (!mYuvMemory) { 1194 ALOGE("%s: unable to create metadata memory", __func__); 1195 return NULL; 1196 } 1197 1198 //Queue YUV buffers in the beginning mQueueAll = true 1199 rc = mYuvMemory->allocate(1, len, true); 1200 if (rc < 0) { 1201 ALOGE("%s: unable to allocate metadata memory", __func__); 1202 delete mYuvMemory; 1203 mYuvMemory = NULL; 1204 return NULL; 1205 } 1206 return mYuvMemory; 1207 } 1208 1209 void QCamera3PicChannel::putStreamBufs() 1210 { 1211 mMemory->unregisterBuffers(); 1212 delete mMemory; 1213 mMemory = NULL; 1214 1215 mYuvMemory->deallocate(); 1216 delete mYuvMemory; 1217 mYuvMemory = NULL; 1218 } 1219 1220 bool QCamera3PicChannel::isRawSnapshot() 1221 { 1222 return !(mJpegSettings->is_jpeg_format); 1223 } 1224 /*=========================================================================== 1225 * FUNCTION : getThumbnailSize 1226 * 1227 * DESCRIPTION: get user set thumbnail size 1228 * 1229 * PARAMETERS : 1230 * @dim : output of thumbnail dimension 1231 * 1232 * RETURN : none 1233 *==========================================================================*/ 1234 void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1235 { 1236 dim = mJpegSettings->thumbnail_size; 1237 } 1238 1239 /*=========================================================================== 1240 * FUNCTION : getJpegQuality 1241 * 1242 * DESCRIPTION: get user set jpeg quality 1243 * 1244 * PARAMETERS : none 1245 * 1246 * RETURN : jpeg quality setting 1247 *==========================================================================*/ 1248 int QCamera3PicChannel::getJpegQuality() 1249 { 1250 int quality = mJpegSettings->jpeg_quality; 1251 if (quality < 0) { 1252 quality = 85; //set to default quality value 1253 } 1254 return quality; 1255 } 1256 1257 /*=========================================================================== 1258 * FUNCTION : getJpegRotation 1259 * 1260 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1261 * 1262 * PARAMETERS : none 1263 * 1264 * RETURN : rotation information 1265 *==========================================================================*/ 1266 int QCamera3PicChannel::getJpegRotation() { 1267 int rotation = mJpegSettings->jpeg_orientation; 1268 if (rotation < 0) { 1269 rotation = 0; 1270 } 1271 return rotation; 1272 } 1273 1274 void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf) 1275 { 1276 m_postprocessor.processPPMetadata(metadata_buf); 1277 } 1278 /*=========================================================================== 1279 * FUNCTION : getRational 1280 * 1281 * DESCRIPTION: compose rational struct 1282 * 1283 * PARAMETERS : 1284 * @rat : ptr to struct to store rational info 1285 * @num :num of the rational 1286 * @denom : denom of the rational 1287 * 1288 * RETURN : int32_t type of status 1289 * NO_ERROR -- success 1290 * none-zero failure code 1291 *==========================================================================*/ 1292 int32_t getRational(rat_t *rat, int num, int denom) 1293 { 1294 if (NULL == rat) { 1295 ALOGE("%s: NULL rat input", __func__); 1296 return BAD_VALUE; 1297 } 1298 rat->num = num; 1299 rat->denom = denom; 1300 return NO_ERROR; 1301 } 1302 1303 /*=========================================================================== 1304 * FUNCTION : getRational 1305 * 1306 * DESCRIPTION: compose rational struct 1307 * 1308 * PARAMETERS : 1309 * @rat : ptr to struct to store rational info 1310 * @num :num of the rational 1311 * @denom : denom of the rational 1312 * 1313 * RETURN : int32_t type of status 1314 * NO_ERROR -- success 1315 * none-zero failure code 1316 *==========================================================================*/ 1317 int32_t getRationalExposureTime(rat_t *rat, double num, double denom) 1318 { 1319 if (NULL == rat) { 1320 ALOGE("%s: NULL rat input", __func__); 1321 return BAD_VALUE; 1322 } 1323 rat->num = num; 1324 rat->denom = round(1.0 / denom); 1325 return NO_ERROR; 1326 } 1327 1328 /*=========================================================================== 1329 * FUNCTION : parseGPSCoordinate 1330 * 1331 * DESCRIPTION: parse GPS coordinate string 1332 * 1333 * PARAMETERS : 1334 * @coord_str : [input] coordinate string 1335 * @coord : [output] ptr to struct to store coordinate 1336 * 1337 * RETURN : int32_t type of status 1338 * NO_ERROR -- success 1339 * none-zero failure code 1340 *==========================================================================*/ 1341 int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1342 { 1343 if(coord == NULL) { 1344 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1345 return BAD_VALUE; 1346 } 1347 float degF = atof(coord_str); 1348 if (degF < 0) { 1349 degF = -degF; 1350 } 1351 float minF = (degF - (int) degF) * 60; 1352 float secF = (minF - (int) minF) * 60; 1353 1354 getRational(&coord[0], (int)degF, 1); 1355 getRational(&coord[1], (int)minF, 1); 1356 getRational(&coord[2], (int)(secF * 10000), 10000); 1357 return NO_ERROR; 1358 } 1359 1360 /*=========================================================================== 1361 * FUNCTION : getExifDateTime 1362 * 1363 * DESCRIPTION: query exif date time 1364 * 1365 * PARAMETERS : 1366 * @dateTime : string to store exif date time 1367 * @count : lenght of the dateTime string 1368 * 1369 * RETURN : int32_t type of status 1370 * NO_ERROR -- success 1371 * none-zero failure code 1372 *==========================================================================*/ 1373 int32_t getExifDateTime(char *dateTime, uint32_t &count) 1374 { 1375 //get time and date from system 1376 time_t rawtime; 1377 struct tm * timeinfo; 1378 time(&rawtime); 1379 timeinfo = localtime (&rawtime); 1380 //Write datetime according to EXIF Spec 1381 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1382 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1383 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1384 timeinfo->tm_mday, timeinfo->tm_hour, 1385 timeinfo->tm_min, timeinfo->tm_sec); 1386 count = 20; 1387 1388 return NO_ERROR; 1389 } 1390 1391 /*=========================================================================== 1392 * FUNCTION : getExifFocalLength 1393 * 1394 * DESCRIPTION: get exif focal lenght 1395 * 1396 * PARAMETERS : 1397 * @focalLength : ptr to rational strcut to store focal lenght 1398 * 1399 * RETURN : int32_t type of status 1400 * NO_ERROR -- success 1401 * none-zero failure code 1402 *==========================================================================*/ 1403 int32_t getExifFocalLength(rat_t *focalLength, float value) 1404 { 1405 int focalLengthValue = 1406 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1407 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1408 } 1409 1410 /*=========================================================================== 1411 * FUNCTION : getExifExpTimeInfo 1412 * 1413 * DESCRIPTION: get exif exposure time information 1414 * 1415 * PARAMETERS : 1416 * @expoTimeInfo : expousure time value 1417 * RETURN : nt32_t type of status 1418 * NO_ERROR -- success 1419 * none-zero failure code 1420 *==========================================================================*/ 1421 int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value) 1422 { 1423 1424 float cal_exposureTime; 1425 if (value != 0) 1426 cal_exposureTime = (double)(value / 1000000000.0); 1427 else 1428 cal_exposureTime = 60.00; 1429 return getRationalExposureTime(expoTimeInfo, 1, cal_exposureTime); 1430 } 1431 1432 /*=========================================================================== 1433 * FUNCTION : getExifGpsProcessingMethod 1434 * 1435 * DESCRIPTION: get GPS processing method 1436 * 1437 * PARAMETERS : 1438 * @gpsProcessingMethod : string to store GPS process method 1439 * @count : lenght of the string 1440 * 1441 * RETURN : int32_t type of status 1442 * NO_ERROR -- success 1443 * none-zero failure code 1444 *==========================================================================*/ 1445 int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1446 uint32_t &count, char* value) 1447 { 1448 if(value != NULL) { 1449 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1450 count = EXIF_ASCII_PREFIX_SIZE; 1451 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1452 count += strlen(value); 1453 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1454 return NO_ERROR; 1455 } else { 1456 return BAD_VALUE; 1457 } 1458 } 1459 1460 /*=========================================================================== 1461 * FUNCTION : getExifLatitude 1462 * 1463 * DESCRIPTION: get exif latitude 1464 * 1465 * PARAMETERS : 1466 * @latitude : ptr to rational struct to store latitude info 1467 * @ladRef : charater to indicate latitude reference 1468 * 1469 * RETURN : int32_t type of status 1470 * NO_ERROR -- success 1471 * none-zero failure code 1472 *==========================================================================*/ 1473 int32_t getExifLatitude(rat_t *latitude, 1474 char *latRef, double value) 1475 { 1476 char str[30]; 1477 snprintf(str, sizeof(str), "%f", value); 1478 if(str != NULL) { 1479 parseGPSCoordinate(str, latitude); 1480 1481 //set Latitude Ref 1482 float latitudeValue = strtof(str, 0); 1483 if(latitudeValue < 0.0f) { 1484 latRef[0] = 'S'; 1485 } else { 1486 latRef[0] = 'N'; 1487 } 1488 latRef[1] = '\0'; 1489 return NO_ERROR; 1490 }else{ 1491 return BAD_VALUE; 1492 } 1493 } 1494 1495 /*=========================================================================== 1496 * FUNCTION : getExifLongitude 1497 * 1498 * DESCRIPTION: get exif longitude 1499 * 1500 * PARAMETERS : 1501 * @longitude : ptr to rational struct to store longitude info 1502 * @lonRef : charater to indicate longitude reference 1503 * 1504 * RETURN : int32_t type of status 1505 * NO_ERROR -- success 1506 * none-zero failure code 1507 *==========================================================================*/ 1508 int32_t getExifLongitude(rat_t *longitude, 1509 char *lonRef, double value) 1510 { 1511 char str[30]; 1512 snprintf(str, sizeof(str), "%f", value); 1513 if(str != NULL) { 1514 parseGPSCoordinate(str, longitude); 1515 1516 //set Longitude Ref 1517 float longitudeValue = strtof(str, 0); 1518 if(longitudeValue < 0.0f) { 1519 lonRef[0] = 'W'; 1520 } else { 1521 lonRef[0] = 'E'; 1522 } 1523 lonRef[1] = '\0'; 1524 return NO_ERROR; 1525 }else{ 1526 return BAD_VALUE; 1527 } 1528 } 1529 1530 /*=========================================================================== 1531 * FUNCTION : getExifAltitude 1532 * 1533 * DESCRIPTION: get exif altitude 1534 * 1535 * PARAMETERS : 1536 * @altitude : ptr to rational struct to store altitude info 1537 * @altRef : charater to indicate altitude reference 1538 * 1539 * RETURN : int32_t type of status 1540 * NO_ERROR -- success 1541 * none-zero failure code 1542 *==========================================================================*/ 1543 int32_t getExifAltitude(rat_t *altitude, 1544 char *altRef, double value) 1545 { 1546 char str[30]; 1547 snprintf(str, sizeof(str), "%f", value); 1548 if(str != NULL) { 1549 double value = atof(str); 1550 *altRef = 0; 1551 if(value < 0){ 1552 *altRef = 1; 1553 value = -value; 1554 } 1555 return getRational(altitude, value*1000, 1000); 1556 }else{ 1557 return BAD_VALUE; 1558 } 1559 } 1560 1561 /*=========================================================================== 1562 * FUNCTION : getExifGpsDateTimeStamp 1563 * 1564 * DESCRIPTION: get exif GPS date time stamp 1565 * 1566 * PARAMETERS : 1567 * @gpsDateStamp : GPS date time stamp string 1568 * @bufLen : length of the string 1569 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1570 * 1571 * RETURN : int32_t type of status 1572 * NO_ERROR -- success 1573 * none-zero failure code 1574 *==========================================================================*/ 1575 int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1576 uint32_t bufLen, 1577 rat_t *gpsTimeStamp, int64_t value) 1578 { 1579 char str[30]; 1580 snprintf(str, sizeof(str), "%lld", value); 1581 if(str != NULL) { 1582 time_t unixTime = (time_t)atol(str); 1583 struct tm *UTCTimestamp = gmtime(&unixTime); 1584 1585 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1586 1587 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1588 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1589 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1590 1591 return NO_ERROR; 1592 } else { 1593 return BAD_VALUE; 1594 } 1595 } 1596 1597 int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1598 cam_rational_type_t step) 1599 { 1600 exposure_val->num = exposure_comp * step.numerator; 1601 exposure_val->denom = step.denominator; 1602 return 0; 1603 } 1604 /*=========================================================================== 1605 * FUNCTION : getExifData 1606 * 1607 * DESCRIPTION: get exif data to be passed into jpeg encoding 1608 * 1609 * PARAMETERS : none 1610 * 1611 * RETURN : exif data from user setting and GPS 1612 *==========================================================================*/ 1613 QCamera3Exif *QCamera3PicChannel::getExifData() 1614 { 1615 QCamera3Exif *exif = new QCamera3Exif(); 1616 if (exif == NULL) { 1617 ALOGE("%s: No memory for QCamera3Exif", __func__); 1618 return NULL; 1619 } 1620 1621 int32_t rc = NO_ERROR; 1622 uint32_t count = 0; 1623 1624 // add exif entries 1625 char dateTime[20]; 1626 memset(dateTime, 0, sizeof(dateTime)); 1627 count = 20; 1628 rc = getExifDateTime(dateTime, count); 1629 if(rc == NO_ERROR) { 1630 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1631 EXIF_ASCII, 1632 count, 1633 (void *)dateTime); 1634 } else { 1635 ALOGE("%s: getExifDateTime failed", __func__); 1636 } 1637 1638 rat_t focalLength; 1639 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1640 if (rc == NO_ERROR) { 1641 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1642 EXIF_RATIONAL, 1643 1, 1644 (void *)&(focalLength)); 1645 } else { 1646 ALOGE("%s: getExifFocalLength failed", __func__); 1647 } 1648 1649 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity; 1650 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1651 EXIF_SHORT, 1652 1, 1653 (void *)&(isoSpeed)); 1654 1655 rat_t sensorExpTime ; 1656 rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time); 1657 if (rc == NO_ERROR){ 1658 exif->addEntry(EXIFTAGID_EXPOSURE_TIME, 1659 EXIF_RATIONAL, 1660 1, 1661 (void *)&(sensorExpTime)); 1662 } else { 1663 ALOGE("now addEntry for EXIFTAGID_EXPOSURE_TIME is %d", sensorExpTime); 1664 } 1665 if (strlen(mJpegSettings->gps_processing_method) > 0) { 1666 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1667 count = 0; 1668 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1669 if(rc == NO_ERROR) { 1670 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1671 EXIF_ASCII, 1672 count, 1673 (void *)gpsProcessingMethod); 1674 } else { 1675 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1676 } 1677 } 1678 1679 if (mJpegSettings->gps_coordinates[0]) { 1680 rat_t latitude[3]; 1681 char latRef[2]; 1682 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0])); 1683 if(rc == NO_ERROR) { 1684 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1685 EXIF_RATIONAL, 1686 3, 1687 (void *)latitude); 1688 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1689 EXIF_ASCII, 1690 2, 1691 (void *)latRef); 1692 } else { 1693 ALOGE("%s: getExifLatitude failed", __func__); 1694 } 1695 } 1696 1697 if (mJpegSettings->gps_coordinates[1]) { 1698 rat_t longitude[3]; 1699 char lonRef[2]; 1700 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1])); 1701 if(rc == NO_ERROR) { 1702 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1703 EXIF_RATIONAL, 1704 3, 1705 (void *)longitude); 1706 1707 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1708 EXIF_ASCII, 1709 2, 1710 (void *)lonRef); 1711 } else { 1712 ALOGE("%s: getExifLongitude failed", __func__); 1713 } 1714 } 1715 1716 if (mJpegSettings->gps_coordinates[2]) { 1717 rat_t altitude; 1718 char altRef; 1719 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2])); 1720 if(rc == NO_ERROR) { 1721 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1722 EXIF_RATIONAL, 1723 1, 1724 (void *)&(altitude)); 1725 1726 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1727 EXIF_BYTE, 1728 1, 1729 (void *)&altRef); 1730 } else { 1731 ALOGE("%s: getExifAltitude failed", __func__); 1732 } 1733 } 1734 1735 if (mJpegSettings->gps_timestamp) { 1736 char gpsDateStamp[20]; 1737 rat_t gpsTimeStamp[3]; 1738 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp)); 1739 if(rc == NO_ERROR) { 1740 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1741 EXIF_ASCII, 1742 strlen(gpsDateStamp) + 1, 1743 (void *)gpsDateStamp); 1744 1745 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1746 EXIF_RATIONAL, 1747 3, 1748 (void *)gpsTimeStamp); 1749 } else { 1750 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1751 } 1752 } 1753 1754 srat_t exposure_val; 1755 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation, 1756 mJpegSettings->exposure_comp_step); 1757 if(rc == NO_ERROR) { 1758 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1759 EXIF_SRATIONAL, 1760 1, 1761 (void *)(&exposure_val)); 1762 } else { 1763 ALOGE("%s: getExifExposureValue failed ", __func__); 1764 } 1765 1766 char value[PROPERTY_VALUE_MAX]; 1767 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 1768 exif->addEntry(EXIFTAGID_MAKE, 1769 EXIF_ASCII, 1770 strlen(value) + 1, 1771 (void *)value); 1772 } else { 1773 ALOGE("%s: getExifMaker failed", __func__); 1774 } 1775 1776 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 1777 exif->addEntry(EXIFTAGID_MODEL, 1778 EXIF_ASCII, 1779 strlen(value) + 1, 1780 (void *)value); 1781 } else { 1782 ALOGE("%s: getExifModel failed", __func__); 1783 } 1784 1785 return exif; 1786 } 1787 1788 int QCamera3PicChannel::kMaxBuffers = 2; 1789 1790 /*=========================================================================== 1791 * FUNCTION : QCamera3ReprocessChannel 1792 * 1793 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1794 * 1795 * PARAMETERS : 1796 * @cam_handle : camera handle 1797 * @cam_ops : ptr to camera ops table 1798 * @pp_mask : post-proccess feature mask 1799 * 1800 * RETURN : none 1801 *==========================================================================*/ 1802 QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle, 1803 mm_camera_ops_t *cam_ops, 1804 channel_cb_routine cb_routine, 1805 cam_padding_info_t *paddingInfo, 1806 void *userData, void *ch_hdl) : 1807 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData), 1808 picChHandle(ch_hdl), 1809 m_pSrcChannel(NULL), 1810 m_pMetaChannel(NULL), 1811 m_metaFrame(NULL), 1812 mMemory(NULL) 1813 { 1814 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 1815 } 1816 1817 1818 /*=========================================================================== 1819 * FUNCTION : QCamera3ReprocessChannel 1820 * 1821 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1822 * 1823 * PARAMETERS : 1824 * @cam_handle : camera handle 1825 * @cam_ops : ptr to camera ops table 1826 * @pp_mask : post-proccess feature mask 1827 * 1828 * RETURN : none 1829 *==========================================================================*/ 1830 int32_t QCamera3ReprocessChannel::initialize() 1831 { 1832 int32_t rc = NO_ERROR; 1833 mm_camera_channel_attr_t attr; 1834 1835 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 1836 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 1837 attr.max_unmatched_frames = 1; 1838 1839 rc = init(&attr, NULL); 1840 if (rc < 0) { 1841 ALOGE("%s: init failed", __func__); 1842 } 1843 return rc; 1844 } 1845 1846 1847 /*=========================================================================== 1848 * FUNCTION : QCamera3ReprocessChannel 1849 * 1850 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1851 * 1852 * PARAMETERS : 1853 * @cam_handle : camera handle 1854 * @cam_ops : ptr to camera ops table 1855 * @pp_mask : post-proccess feature mask 1856 * 1857 * RETURN : none 1858 *==========================================================================*/ 1859 void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1860 QCamera3Stream *stream) 1861 { 1862 //Got the pproc data callback. Now send to jpeg encoding 1863 uint8_t frameIndex; 1864 mm_camera_super_buf_t* frame = NULL; 1865 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle; 1866 1867 if(!super_frame) { 1868 ALOGE("%s: Invalid Super buffer",__func__); 1869 return; 1870 } 1871 1872 if(super_frame->num_bufs != 1) { 1873 ALOGE("%s: Multiple streams are not supported",__func__); 1874 return; 1875 } 1876 if(super_frame->bufs[0] == NULL ) { 1877 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1878 __func__); 1879 return; 1880 } 1881 1882 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1883 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1884 if (frame == NULL) { 1885 ALOGE("%s: Error allocating memory to save received_frame structure.", 1886 __func__); 1887 if(stream) { 1888 stream->bufDone(frameIndex); 1889 } 1890 return; 1891 } 1892 *frame = *super_frame; 1893 //queue back the metadata buffer 1894 if (m_metaFrame != NULL) { 1895 ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(m_metaFrame); 1896 free(m_metaFrame); 1897 m_metaFrame = NULL; 1898 } else { 1899 ALOGE("%s: Meta frame was NULL", __func__); 1900 } 1901 obj->m_postprocessor.processPPData(frame); 1902 return; 1903 } 1904 1905 /*=========================================================================== 1906 * FUNCTION : QCamera3ReprocessChannel 1907 * 1908 * DESCRIPTION: default constructor of QCamera3ReprocessChannel 1909 * 1910 * PARAMETERS : none 1911 * 1912 * RETURN : none 1913 *==========================================================================*/ 1914 QCamera3ReprocessChannel::QCamera3ReprocessChannel() : 1915 m_pSrcChannel(NULL), 1916 m_pMetaChannel(NULL), 1917 m_metaFrame(NULL) 1918 { 1919 } 1920 1921 /*=========================================================================== 1922 * FUNCTION : QCamera3ReprocessChannel 1923 * 1924 * DESCRIPTION: register the buffers of the reprocess channel 1925 * 1926 * PARAMETERS : none 1927 * 1928 * RETURN : none 1929 *==========================================================================*/ 1930 int32_t QCamera3ReprocessChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 1931 { 1932 return 0; 1933 } 1934 1935 /*=========================================================================== 1936 * FUNCTION : getStreamBufs 1937 * 1938 * DESCRIPTION: register the buffers of the reprocess channel 1939 * 1940 * PARAMETERS : none 1941 * 1942 * RETURN : QCamera3Memory * 1943 *==========================================================================*/ 1944 QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len) 1945 { 1946 int rc = 0; 1947 1948 mMemory = new QCamera3HeapMemory(); 1949 if (!mMemory) { 1950 ALOGE("%s: unable to create reproc memory", __func__); 1951 return NULL; 1952 } 1953 1954 //Queue YUV buffers in the beginning mQueueAll = true 1955 rc = mMemory->allocate(2, len, true); 1956 if (rc < 0) { 1957 ALOGE("%s: unable to allocate reproc memory", __func__); 1958 delete mMemory; 1959 mMemory = NULL; 1960 return NULL; 1961 } 1962 return mMemory; 1963 } 1964 1965 /*=========================================================================== 1966 * FUNCTION : getStreamBufs 1967 * 1968 * DESCRIPTION: register the buffers of the reprocess channel 1969 * 1970 * PARAMETERS : none 1971 * 1972 * RETURN : 1973 *==========================================================================*/ 1974 void QCamera3ReprocessChannel::putStreamBufs() 1975 { 1976 mMemory->deallocate(); 1977 delete mMemory; 1978 mMemory = NULL; 1979 } 1980 1981 /*=========================================================================== 1982 * FUNCTION : ~QCamera3ReprocessChannel 1983 * 1984 * DESCRIPTION: destructor of QCamera3ReprocessChannel 1985 * 1986 * PARAMETERS : none 1987 * 1988 * RETURN : none 1989 *==========================================================================*/ 1990 QCamera3ReprocessChannel::~QCamera3ReprocessChannel() 1991 { 1992 } 1993 1994 /*=========================================================================== 1995 * FUNCTION : getStreamBySourceHandle 1996 * 1997 * DESCRIPTION: find reprocess stream by its source stream handle 1998 * 1999 * PARAMETERS : 2000 * @srcHandle : source stream handle 2001 * 2002 * RETURN : ptr to reprocess stream if found. NULL if not found 2003 *==========================================================================*/ 2004 QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle) 2005 { 2006 QCamera3Stream *pStream = NULL; 2007 2008 for (int i = 0; i < m_numStreams; i++) { 2009 if (mSrcStreamHandles[i] == srcHandle) { 2010 pStream = mStreams[i]; 2011 break; 2012 } 2013 } 2014 return pStream; 2015 } 2016 2017 /*=========================================================================== 2018 * FUNCTION : doReprocess 2019 * 2020 * DESCRIPTION: request to do a reprocess on the frame 2021 * 2022 * PARAMETERS : 2023 * @frame : frame to be performed a reprocess 2024 * 2025 * RETURN : int32_t type of status 2026 * NO_ERROR -- success 2027 * none-zero failure code 2028 *==========================================================================*/ 2029 int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 2030 mm_camera_super_buf_t *meta_frame) 2031 { 2032 int32_t rc = 0; 2033 if (m_numStreams < 1) { 2034 ALOGE("%s: No reprocess stream is created", __func__); 2035 return -1; 2036 } 2037 if (m_pSrcChannel == NULL) { 2038 ALOGE("%s: No source channel for reprocess", __func__); 2039 return -1; 2040 } 2041 m_metaFrame = meta_frame; 2042 for (int i = 0; i < frame->num_bufs; i++) { 2043 QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id); 2044 if (pStream != NULL) { 2045 cam_stream_parm_buffer_t param; 2046 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2047 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2048 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 2049 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 2050 if (meta_frame != NULL) { 2051 param.reprocess.meta_present = 1; 2052 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2053 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2054 } 2055 rc = pStream->setParameter(param); 2056 if (rc != NO_ERROR) { 2057 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2058 break; 2059 } 2060 } 2061 } 2062 return rc; 2063 } 2064 2065 /*=========================================================================== 2066 * FUNCTION : doReprocess 2067 * 2068 * DESCRIPTION: request to do a reprocess on the frame 2069 * 2070 * PARAMETERS : 2071 * @buf_fd : fd to the input buffer that needs reprocess 2072 * @buf_lenght : length of the input buffer 2073 * @ret_val : result of reprocess. 2074 * Example: Could be faceID in case of register face image. 2075 * 2076 * RETURN : int32_t type of status 2077 * NO_ERROR -- success 2078 * none-zero failure code 2079 *==========================================================================*/ 2080 int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd, 2081 uint32_t buf_length, 2082 int32_t &ret_val, 2083 mm_camera_super_buf_t *meta_frame) 2084 { 2085 int32_t rc = 0; 2086 if (m_numStreams < 1) { 2087 ALOGE("%s: No reprocess stream is created", __func__); 2088 return -1; 2089 } 2090 if (meta_frame == NULL) { 2091 ALOGE("%s: Did not get corresponding metadata in time", __func__); 2092 return -1; 2093 } 2094 2095 uint32_t buf_idx = 0; 2096 for (int i = 0; i < m_numStreams; i++) { 2097 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2098 buf_idx, -1, 2099 buf_fd, buf_length); 2100 2101 if (rc == NO_ERROR) { 2102 cam_stream_parm_buffer_t param; 2103 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2104 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2105 param.reprocess.buf_index = buf_idx; 2106 param.reprocess.meta_present = 1; 2107 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2108 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2109 rc = mStreams[i]->setParameter(param); 2110 if (rc == NO_ERROR) { 2111 ret_val = param.reprocess.ret_val; 2112 } 2113 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2114 buf_idx, -1); 2115 } 2116 } 2117 return rc; 2118 } 2119 2120 /*=========================================================================== 2121 * FUNCTION : addReprocStreamsFromSource 2122 * 2123 * DESCRIPTION: add reprocess streams from input source channel 2124 * 2125 * PARAMETERS : 2126 * @config : pp feature configuration 2127 * @pSrcChannel : ptr to input source channel that needs reprocess 2128 * @pMetaChannel : ptr to metadata channel to get corresp. metadata 2129 * 2130 * RETURN : int32_t type of status 2131 * NO_ERROR -- success 2132 * none-zero failure code 2133 *==========================================================================*/ 2134 int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config, 2135 QCamera3Channel *pSrcChannel, 2136 QCamera3Channel *pMetaChannel) 2137 { 2138 int32_t rc = 0; 2139 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0); 2140 if (pSrcStream == NULL) { 2141 ALOGE("%s: source channel doesn't have a stream", __func__); 2142 return BAD_VALUE; 2143 } 2144 cam_stream_reproc_config_t reprocess_config; 2145 cam_dimension_t streamDim; 2146 cam_stream_type_t streamType; 2147 cam_format_t streamFormat; 2148 cam_frame_len_offset_t frameOffset; 2149 int num_buffers = 2; 2150 2151 streamType = CAM_STREAM_TYPE_OFFLINE_PROC; 2152 pSrcStream->getFormat(streamFormat); 2153 pSrcStream->getFrameDimension(streamDim); 2154 pSrcStream->getFrameOffset(frameOffset); 2155 2156 reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE; 2157 reprocess_config.online.input_stream_id = pSrcStream->getMyServerID(); 2158 reprocess_config.online.input_stream_type = pSrcStream->getMyType(); 2159 reprocess_config.pp_feature_config = config; 2160 2161 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle(); 2162 2163 if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 2164 if (reprocess_config.pp_feature_config.rotation == ROTATE_90 || 2165 reprocess_config.pp_feature_config.rotation == ROTATE_270) { 2166 // rotated by 90 or 270, need to switch width and height 2167 int32_t temp = streamDim.height; 2168 streamDim.height = streamDim.width; 2169 streamDim.width = temp; 2170 } 2171 } 2172 2173 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 2174 m_handle, 2175 m_camOps, 2176 mPaddingInfo, 2177 (QCamera3Channel*)this); 2178 if (pStream == NULL) { 2179 ALOGE("%s: No mem for Stream", __func__); 2180 return NO_MEMORY; 2181 } 2182 2183 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config, 2184 num_buffers,QCamera3Channel::streamCbRoutine, this); 2185 2186 2187 if (rc == 0) { 2188 mStreams[m_numStreams] = pStream; 2189 m_numStreams++; 2190 } else { 2191 ALOGE("%s: failed to create reprocess stream", __func__); 2192 delete pStream; 2193 } 2194 2195 if (rc == NO_ERROR) { 2196 m_pSrcChannel = pSrcChannel; 2197 m_pMetaChannel = pMetaChannel; 2198 } 2199 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 2200 ALOGE("%s: Request for super buffer failed",__func__); 2201 } 2202 return rc; 2203 } 2204 2205 2206 }; // namespace qcamera 2207