1 /* Copyright (c) 2012-2014, 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 "QCamera3Stream" 31 //#define LOG_NDEBUG 0 32 33 #include <utils/Log.h> 34 #include <utils/Errors.h> 35 #include "QCamera3HWI.h" 36 #include "QCamera3Stream.h" 37 #include "QCamera3Channel.h" 38 39 using namespace android; 40 41 namespace qcamera { 42 43 /*=========================================================================== 44 * FUNCTION : get_bufs 45 * 46 * DESCRIPTION: static function entry to allocate stream buffers 47 * 48 * PARAMETERS : 49 * @offset : offset info of stream buffers 50 * @num_bufs : number of buffers allocated 51 * @initial_reg_flag: flag to indicate if buffer needs to be registered 52 * at kernel initially 53 * @bufs : output of allocated buffers 54 * @ops_tbl : ptr to buf mapping/unmapping ops 55 * @user_data : user data ptr of ops_tbl 56 * 57 * RETURN : int32_t type of status 58 * NO_ERROR -- success 59 * none-zero failure code 60 *==========================================================================*/ 61 int32_t QCamera3Stream::get_bufs( 62 cam_frame_len_offset_t *offset, 63 uint8_t *num_bufs, 64 uint8_t **initial_reg_flag, 65 mm_camera_buf_def_t **bufs, 66 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 67 void *user_data) 68 { 69 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data); 70 if (!stream) { 71 ALOGE("getBufs invalid stream pointer"); 72 return NO_MEMORY; 73 } 74 return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl); 75 } 76 77 /*=========================================================================== 78 * FUNCTION : put_bufs 79 * 80 * DESCRIPTION: static function entry to deallocate stream buffers 81 * 82 * PARAMETERS : 83 * @ops_tbl : ptr to buf mapping/unmapping ops 84 * @user_data : user data ptr of ops_tbl 85 * 86 * RETURN : int32_t type of status 87 * NO_ERROR -- success 88 * none-zero failure code 89 *==========================================================================*/ 90 int32_t QCamera3Stream::put_bufs( 91 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 92 void *user_data) 93 { 94 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data); 95 if (!stream) { 96 ALOGE("putBufs invalid stream pointer"); 97 return NO_MEMORY; 98 } 99 return stream->putBufs(ops_tbl); 100 } 101 102 /*=========================================================================== 103 * FUNCTION : invalidate_buf 104 * 105 * DESCRIPTION: static function entry to invalidate a specific stream buffer 106 * 107 * PARAMETERS : 108 * @index : index of the stream buffer to invalidate 109 * @user_data : user data ptr of ops_tbl 110 * 111 * RETURN : int32_t type of status 112 * NO_ERROR -- success 113 * none-zero failure code 114 *==========================================================================*/ 115 int32_t QCamera3Stream::invalidate_buf(int index, void *user_data) 116 { 117 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data); 118 if (!stream) { 119 ALOGE("invalid stream pointer"); 120 return NO_MEMORY; 121 } 122 return stream->invalidateBuf(index); 123 } 124 125 /*=========================================================================== 126 * FUNCTION : clean_invalidate_buf 127 * 128 * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer 129 * 130 * PARAMETERS : 131 * @index : index of the stream buffer to invalidate 132 * @user_data : user data ptr of ops_tbl 133 * 134 * RETURN : int32_t type of status 135 * NO_ERROR -- success 136 * none-zero failure code 137 *==========================================================================*/ 138 int32_t QCamera3Stream::clean_invalidate_buf(int index, void *user_data) 139 { 140 QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data); 141 if (!stream) { 142 ALOGE("invalid stream pointer"); 143 return NO_MEMORY; 144 } 145 return stream->cleanInvalidateBuf(index); 146 } 147 148 /*=========================================================================== 149 * FUNCTION : QCamera3Stream 150 * 151 * DESCRIPTION: constructor of QCamera3Stream 152 * 153 * PARAMETERS : 154 * @allocator : memory allocator obj 155 * @camHandle : camera handle 156 * @chId : channel handle 157 * @camOps : ptr to camera ops table 158 * @paddingInfo: ptr to padding info 159 * 160 * RETURN : None 161 *==========================================================================*/ 162 QCamera3Stream::QCamera3Stream(uint32_t camHandle, 163 uint32_t chId, 164 mm_camera_ops_t *camOps, 165 cam_padding_info_t *paddingInfo, 166 QCamera3Channel *channel) : 167 mCamHandle(camHandle), 168 mChannelHandle(chId), 169 mHandle(0), 170 mCamOps(camOps), 171 mStreamInfo(NULL), 172 mMemOps(NULL), 173 mNumBufs(0), 174 mDataCB(NULL), 175 mUserData(NULL), 176 mDataQ(releaseFrameData, this), 177 mStreamInfoBuf(NULL), 178 mStreamBufs(NULL), 179 mBufDefs(NULL), 180 mChannel(channel), 181 m_bActive(false) 182 { 183 mMemVtbl.user_data = this; 184 mMemVtbl.get_bufs = get_bufs; 185 mMemVtbl.put_bufs = put_bufs; 186 mMemVtbl.invalidate_buf = invalidate_buf; 187 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf; 188 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 189 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t)); 190 } 191 192 /*=========================================================================== 193 * FUNCTION : ~QCamera3Stream 194 * 195 * DESCRIPTION: deconstructor of QCamera3Stream 196 * 197 * PARAMETERS : None 198 * 199 * RETURN : None 200 *==========================================================================*/ 201 QCamera3Stream::~QCamera3Stream() 202 { 203 if (mStreamInfoBuf != NULL) { 204 int rc = mCamOps->unmap_stream_buf(mCamHandle, 205 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1); 206 if (rc < 0) { 207 ALOGE("Failed to map stream info buffer"); 208 } 209 mStreamInfoBuf->deallocate(); 210 delete mStreamInfoBuf; 211 mStreamInfoBuf = NULL; 212 } 213 214 // delete stream 215 if (mHandle > 0) { 216 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 217 mHandle = 0; 218 } 219 } 220 221 /*=========================================================================== 222 * FUNCTION : init 223 * 224 * DESCRIPTION: initialize stream obj 225 * 226 * PARAMETERS : 227 * @streamInfoBuf: ptr to buf that contains stream info 228 * @stream_cb : stream data notify callback. Can be NULL if not needed 229 * @userdata : user data ptr 230 * 231 * RETURN : int32_t type of status 232 * NO_ERROR -- success 233 * none-zero failure code 234 *==========================================================================*/ 235 int32_t QCamera3Stream::init(cam_stream_type_t streamType, 236 cam_format_t streamFormat, 237 cam_dimension_t streamDim, 238 cam_stream_reproc_config_t* reprocess_config, 239 uint8_t minNumBuffers, 240 stream_cb_routine stream_cb, 241 void *userdata) 242 { 243 int32_t rc = OK; 244 mm_camera_stream_config_t stream_config; 245 246 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle); 247 if (!mHandle) { 248 ALOGE("add_stream failed"); 249 rc = UNKNOWN_ERROR; 250 goto done; 251 } 252 253 // allocate and map stream info memory 254 mStreamInfoBuf = new QCamera3HeapMemory(); 255 if (mStreamInfoBuf == NULL) { 256 ALOGE("%s: no memory for stream info buf obj", __func__); 257 rc = -ENOMEM; 258 goto err1; 259 } 260 rc = mStreamInfoBuf->allocate(1, sizeof(cam_stream_info_t), false); 261 if (rc < 0) { 262 ALOGE("%s: no memory for stream info", __func__); 263 rc = -ENOMEM; 264 goto err2; 265 } 266 267 mStreamInfo = 268 reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0)); 269 memset(mStreamInfo, 0, sizeof(cam_stream_info_t)); 270 mStreamInfo->stream_type = streamType; 271 mStreamInfo->fmt = streamFormat; 272 mStreamInfo->dim = streamDim; 273 mStreamInfo->num_bufs = minNumBuffers; 274 275 rc = mCamOps->map_stream_buf(mCamHandle, 276 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 277 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0)); 278 if (rc < 0) { 279 ALOGE("Failed to map stream info buffer"); 280 goto err3; 281 } 282 283 mNumBufs = minNumBuffers; 284 if (reprocess_config != NULL) { 285 mStreamInfo->reprocess_config = *reprocess_config; 286 mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 287 //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs; 288 mStreamInfo->num_of_burst = 1; 289 ALOGI("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst); 290 } else { 291 mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 292 } 293 294 // Configure the stream 295 stream_config.stream_info = mStreamInfo; 296 stream_config.mem_vtbl = mMemVtbl; 297 stream_config.padding_info = mPaddingInfo; 298 stream_config.userdata = this; 299 stream_config.stream_cb = dataNotifyCB; 300 301 rc = mCamOps->config_stream(mCamHandle, 302 mChannelHandle, mHandle, &stream_config); 303 if (rc < 0) { 304 ALOGE("Failed to config stream, rc = %d", rc); 305 goto err4; 306 } 307 308 mDataCB = stream_cb; 309 mUserData = userdata; 310 return 0; 311 312 err4: 313 mCamOps->unmap_stream_buf(mCamHandle, 314 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1); 315 err3: 316 mStreamInfoBuf->deallocate(); 317 err2: 318 delete mStreamInfoBuf; 319 mStreamInfoBuf = NULL; 320 mStreamInfo = NULL; 321 err1: 322 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 323 mHandle = 0; 324 mNumBufs = 0; 325 done: 326 return rc; 327 } 328 329 /*=========================================================================== 330 * FUNCTION : start 331 * 332 * DESCRIPTION: start stream. Will start main stream thread to handle stream 333 * related ops. 334 * 335 * PARAMETERS : none 336 * 337 * RETURN : int32_t type of status 338 * NO_ERROR -- success 339 * none-zero failure code 340 *==========================================================================*/ 341 int32_t QCamera3Stream::start() 342 { 343 int32_t rc = 0; 344 rc = mProcTh.launch(dataProcRoutine, this); 345 if (rc == NO_ERROR) { 346 m_bActive = true; 347 } 348 return rc; 349 } 350 351 /*=========================================================================== 352 * FUNCTION : stop 353 * 354 * DESCRIPTION: stop stream. Will stop main stream thread 355 * 356 * PARAMETERS : none 357 * 358 * RETURN : int32_t type of status 359 * NO_ERROR -- success 360 * none-zero failure code 361 *==========================================================================*/ 362 int32_t QCamera3Stream::stop() 363 { 364 int32_t rc = 0; 365 rc = mProcTh.exit(); 366 m_bActive = false; 367 return rc; 368 } 369 370 /*=========================================================================== 371 * FUNCTION : processDataNotify 372 * 373 * DESCRIPTION: process stream data notify 374 * 375 * PARAMETERS : 376 * @frame : stream frame received 377 * 378 * RETURN : int32_t type of status 379 * NO_ERROR -- success 380 * none-zero failure code 381 *==========================================================================*/ 382 int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame) 383 { 384 ALOGV("%s: E\n", __func__); 385 int32_t rc; 386 if (m_bActive) { 387 mDataQ.enqueue((void *)frame); 388 rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 389 } else { 390 ALOGD("%s: Stream thread is not active, no ops here", __func__); 391 bufDone(frame->bufs[0]->buf_idx); 392 free(frame); 393 rc = NO_ERROR; 394 } 395 ALOGV("%s: X\n", __func__); 396 return rc; 397 } 398 399 /*=========================================================================== 400 * FUNCTION : dataNotifyCB 401 * 402 * DESCRIPTION: callback for data notify. This function is registered with 403 * mm-camera-interface to handle data notify 404 * 405 * PARAMETERS : 406 * @recvd_frame : stream frame received 407 * userdata : user data ptr 408 * 409 * RETURN : none 410 *==========================================================================*/ 411 void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 412 void *userdata) 413 { 414 ALOGV("%s: E\n", __func__); 415 QCamera3Stream* stream = (QCamera3Stream *)userdata; 416 if (stream == NULL || 417 recvd_frame == NULL || 418 recvd_frame->bufs[0] == NULL || 419 recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) { 420 ALOGE("%s: Not a valid stream to handle buf", __func__); 421 return; 422 } 423 424 mm_camera_super_buf_t *frame = 425 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 426 if (frame == NULL) { 427 ALOGE("%s: No mem for mm_camera_buf_def_t", __func__); 428 stream->bufDone(recvd_frame->bufs[0]->buf_idx); 429 return; 430 } 431 *frame = *recvd_frame; 432 stream->processDataNotify(frame); 433 return; 434 } 435 436 /*=========================================================================== 437 * FUNCTION : dataProcRoutine 438 * 439 * DESCRIPTION: function to process data in the main stream thread 440 * 441 * PARAMETERS : 442 * @data : user data ptr 443 * 444 * RETURN : none 445 *==========================================================================*/ 446 void *QCamera3Stream::dataProcRoutine(void *data) 447 { 448 int running = 1; 449 int ret; 450 QCamera3Stream *pme = (QCamera3Stream *)data; 451 QCameraCmdThread *cmdThread = &pme->mProcTh; 452 cmdThread->setName("cam_stream_proc"); 453 454 ALOGV("%s: E", __func__); 455 do { 456 do { 457 ret = cam_sem_wait(&cmdThread->cmd_sem); 458 if (ret != 0 && errno != EINVAL) { 459 ALOGE("%s: cam_sem_wait error (%s)", 460 __func__, strerror(errno)); 461 return NULL; 462 } 463 } while (ret != 0); 464 465 // we got notified about new cmd avail in cmd queue 466 camera_cmd_type_t cmd = cmdThread->getCmd(); 467 switch (cmd) { 468 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 469 { 470 ALOGV("%s: Do next job", __func__); 471 mm_camera_super_buf_t *frame = 472 (mm_camera_super_buf_t *)pme->mDataQ.dequeue(); 473 if (NULL != frame) { 474 if (pme->mDataCB != NULL) { 475 pme->mDataCB(frame, pme, pme->mUserData); 476 } else { 477 // no data cb routine, return buf here 478 pme->bufDone(frame->bufs[0]->buf_idx); 479 } 480 } 481 } 482 break; 483 case CAMERA_CMD_TYPE_EXIT: 484 ALOGD("%s: Exit", __func__); 485 /* flush data buf queue */ 486 pme->mDataQ.flush(); 487 running = 0; 488 break; 489 default: 490 break; 491 } 492 } while (running); 493 ALOGV("%s: X", __func__); 494 return NULL; 495 } 496 497 /*=========================================================================== 498 * FUNCTION : getInternalFormatBuffer 499 * 500 * DESCRIPTION: return buffer in the internal format structure 501 * 502 * PARAMETERS : 503 * @index : index of buffer to be returned 504 * 505 * RETURN : int32_t type of status 506 * NO_ERROR -- success 507 * none-zero failure code 508 *==========================================================================*/ 509 mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index) 510 { 511 mm_camera_buf_def_t *rc = NULL; 512 if ((index >= mNumBufs) || (mBufDefs == NULL) || 513 (NULL == mBufDefs[index].mem_info)) { 514 ALOGE("%s:Index out of range/no internal buffers yet", __func__); 515 return NULL; 516 } 517 518 rc = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t)); 519 if(rc) { 520 memcpy(rc, &mBufDefs[index], sizeof(mm_camera_buf_def_t)); 521 } else { 522 ALOGE("%s: Failed to allocate memory",__func__); 523 } 524 return rc; 525 } 526 527 /*=========================================================================== 528 * FUNCTION : bufDone 529 * 530 * DESCRIPTION: return stream buffer to kernel 531 * 532 * PARAMETERS : 533 * @index : index of buffer to be returned 534 * 535 * RETURN : int32_t type of status 536 * NO_ERROR -- success 537 * none-zero failure code 538 *==========================================================================*/ 539 int32_t QCamera3Stream::bufDone(int index) 540 { 541 int32_t rc = NO_ERROR; 542 543 if (index >= mNumBufs || mBufDefs == NULL) 544 return BAD_INDEX; 545 546 if( NULL == mBufDefs[index].mem_info) { 547 if (NULL == mMemOps) { 548 ALOGE("%s: Camera operations not initialized", __func__); 549 return NO_INIT; 550 } 551 552 rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index), 553 mStreamBufs->getSize(index), mMemOps->userdata); 554 if (rc < 0) { 555 ALOGE("%s: Failed to map camera buffer %d", __func__, index); 556 return rc; 557 } 558 559 rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index); 560 if (NO_ERROR != rc) { 561 ALOGE("%s: Couldn't find camera buffer definition", __func__); 562 mMemOps->unmap_ops(index, -1, mMemOps->userdata); 563 return rc; 564 } 565 } 566 567 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]); 568 if (rc < 0) 569 return FAILED_TRANSACTION; 570 571 return rc; 572 } 573 574 /*=========================================================================== 575 * FUNCTION : getBufs 576 * 577 * DESCRIPTION: allocate stream buffers 578 * 579 * PARAMETERS : 580 * @offset : offset info of stream buffers 581 * @num_bufs : number of buffers allocated 582 * @initial_reg_flag: flag to indicate if buffer needs to be registered 583 * at kernel initially 584 * @bufs : output of allocated buffers 585 * @ops_tbl : ptr to buf mapping/unmapping ops 586 * 587 * RETURN : int32_t type of status 588 * NO_ERROR -- success 589 * none-zero failure code 590 *==========================================================================*/ 591 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset, 592 uint8_t *num_bufs, 593 uint8_t **initial_reg_flag, 594 mm_camera_buf_def_t **bufs, 595 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 596 { 597 int rc = NO_ERROR; 598 uint8_t *regFlags; 599 600 if (!ops_tbl) { 601 ALOGE("%s: ops_tbl is NULL", __func__); 602 return INVALID_OPERATION; 603 } 604 605 mFrameLenOffset = *offset; 606 mMemOps = ops_tbl; 607 608 mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len); 609 if (!mStreamBufs) { 610 ALOGE("%s: Failed to allocate stream buffers", __func__); 611 return NO_MEMORY; 612 } 613 614 int registeredBuffers = mStreamBufs->getCnt(); 615 for (int i = 0; i < registeredBuffers; i++) { 616 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i), 617 mStreamBufs->getSize(i), ops_tbl->userdata); 618 if (rc < 0) { 619 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 620 for (int j = 0; j < i; j++) { 621 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata); 622 } 623 return INVALID_OPERATION; 624 } 625 } 626 627 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 628 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 629 if (!regFlags) { 630 ALOGE("%s: Out of memory", __func__); 631 for (int i = 0; i < registeredBuffers; i++) { 632 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 633 } 634 return NO_MEMORY; 635 } 636 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 637 638 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 639 if (mBufDefs == NULL) { 640 ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc); 641 for (int i = 0; i < registeredBuffers; i++) { 642 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 643 } 644 free(regFlags); 645 regFlags = NULL; 646 return INVALID_OPERATION; 647 } 648 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 649 for (int i = 0; i < registeredBuffers; i++) { 650 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 651 } 652 653 rc = mStreamBufs->getRegFlags(regFlags); 654 if (rc < 0) { 655 ALOGE("%s: getRegFlags failed %d", __func__, rc); 656 for (int i = 0; i < registeredBuffers; i++) { 657 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 658 } 659 free(mBufDefs); 660 mBufDefs = NULL; 661 free(regFlags); 662 regFlags = NULL; 663 return INVALID_OPERATION; 664 } 665 666 *num_bufs = mNumBufs; 667 *initial_reg_flag = regFlags; 668 *bufs = mBufDefs; 669 return NO_ERROR; 670 } 671 672 /*=========================================================================== 673 * FUNCTION : putBufs 674 * 675 * DESCRIPTION: deallocate stream buffers 676 * 677 * PARAMETERS : 678 * @ops_tbl : ptr to buf mapping/unmapping ops 679 * 680 * RETURN : int32_t type of status 681 * NO_ERROR -- success 682 * none-zero failure code 683 *==========================================================================*/ 684 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 685 { 686 int rc = NO_ERROR; 687 for (int i = 0; i < mNumBufs; i++) { 688 if (NULL != mBufDefs[i].mem_info) { 689 rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 690 if (rc < 0) { 691 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 692 } 693 } 694 } 695 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer 696 // mm-camera-interface own the buffer, so no need to free 697 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 698 mChannel->putStreamBufs(); 699 700 return rc; 701 } 702 703 /*=========================================================================== 704 * FUNCTION : invalidateBuf 705 * 706 * DESCRIPTION: invalidate a specific stream buffer 707 * 708 * PARAMETERS : 709 * @index : index of the buffer to invalidate 710 * 711 * RETURN : int32_t type of status 712 * NO_ERROR -- success 713 * none-zero failure code 714 *==========================================================================*/ 715 int32_t QCamera3Stream::invalidateBuf(int index) 716 { 717 return mStreamBufs->invalidateCache(index); 718 } 719 720 /*=========================================================================== 721 * FUNCTION : cleanInvalidateBuf 722 * 723 * DESCRIPTION: clean and invalidate a specific stream buffer 724 * 725 * PARAMETERS : 726 * @index : index of the buffer to invalidate 727 * 728 * RETURN : int32_t type of status 729 * NO_ERROR -- success 730 * none-zero failure code 731 *==========================================================================*/ 732 int32_t QCamera3Stream::cleanInvalidateBuf(int index) 733 { 734 return mStreamBufs->cleanInvalidateCache(index); 735 } 736 737 /*=========================================================================== 738 * FUNCTION : getFrameOffset 739 * 740 * DESCRIPTION: query stream buffer frame offset info 741 * 742 * PARAMETERS : 743 * @offset : reference to struct to store the queried frame offset info 744 * 745 * RETURN : int32_t type of status 746 * NO_ERROR -- success 747 * none-zero failure code 748 *==========================================================================*/ 749 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset) 750 { 751 offset = mFrameLenOffset; 752 return 0; 753 } 754 755 /*=========================================================================== 756 * FUNCTION : getFrameDimension 757 * 758 * DESCRIPTION: query stream frame dimension info 759 * 760 * PARAMETERS : 761 * @dim : reference to struct to store the queried frame dimension 762 * 763 * RETURN : int32_t type of status 764 * NO_ERROR -- success 765 * none-zero failure code 766 *==========================================================================*/ 767 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim) 768 { 769 if (mStreamInfo != NULL) { 770 dim = mStreamInfo->dim; 771 return 0; 772 } 773 return -1; 774 } 775 776 /*=========================================================================== 777 * FUNCTION : getFormat 778 * 779 * DESCRIPTION: query stream format 780 * 781 * PARAMETERS : 782 * @fmt : reference to stream format 783 * 784 * RETURN : int32_t type of status 785 * NO_ERROR -- success 786 * none-zero failure code 787 *==========================================================================*/ 788 int32_t QCamera3Stream::getFormat(cam_format_t &fmt) 789 { 790 if (mStreamInfo != NULL) { 791 fmt = mStreamInfo->fmt; 792 return 0; 793 } 794 return -1; 795 } 796 797 /*=========================================================================== 798 * FUNCTION : getMyServerID 799 * 800 * DESCRIPTION: query server stream ID 801 * 802 * PARAMETERS : None 803 * 804 * RETURN : stream ID from server 805 *==========================================================================*/ 806 uint32_t QCamera3Stream::getMyServerID() { 807 if (mStreamInfo != NULL) { 808 return mStreamInfo->stream_svr_id; 809 } else { 810 return 0; 811 } 812 } 813 814 /*=========================================================================== 815 * FUNCTION : getMyType 816 * 817 * DESCRIPTION: query stream type 818 * 819 * PARAMETERS : None 820 * 821 * RETURN : type of stream 822 *==========================================================================*/ 823 cam_stream_type_t QCamera3Stream::getMyType() const 824 { 825 if (mStreamInfo != NULL) { 826 return mStreamInfo->stream_type; 827 } else { 828 return CAM_STREAM_TYPE_MAX; 829 } 830 } 831 832 /*=========================================================================== 833 * FUNCTION : mapBuf 834 * 835 * DESCRIPTION: map stream related buffer to backend server 836 * 837 * PARAMETERS : 838 * @buf_type : mapping type of buffer 839 * @buf_idx : index of buffer 840 * @plane_idx: plane index 841 * @fd : fd of the buffer 842 * @size : lenght of the buffer 843 * 844 * RETURN : int32_t type of status 845 * NO_ERROR -- success 846 * none-zero failure code 847 *==========================================================================*/ 848 int32_t QCamera3Stream::mapBuf(uint8_t buf_type, 849 uint32_t buf_idx, 850 int32_t plane_idx, 851 int fd, 852 uint32_t size) 853 { 854 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle, 855 mHandle, buf_type, 856 buf_idx, plane_idx, 857 fd, size); 858 859 } 860 861 /*=========================================================================== 862 * FUNCTION : unmapBuf 863 * 864 * DESCRIPTION: unmap stream related buffer to backend server 865 * 866 * PARAMETERS : 867 * @buf_type : mapping type of buffer 868 * @buf_idx : index of buffer 869 * @plane_idx: plane index 870 * 871 * RETURN : int32_t type of status 872 * NO_ERROR -- success 873 * none-zero failure code 874 *==========================================================================*/ 875 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx) 876 { 877 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, 878 mHandle, buf_type, 879 buf_idx, plane_idx); 880 } 881 882 /*=========================================================================== 883 * FUNCTION : setParameter 884 * 885 * DESCRIPTION: set stream based parameters 886 * 887 * PARAMETERS : 888 * @param : ptr to parameters to be set 889 * 890 * RETURN : int32_t type of status 891 * NO_ERROR -- success 892 * none-zero failure code 893 *==========================================================================*/ 894 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t ¶m) 895 { 896 int32_t rc = NO_ERROR; 897 mStreamInfo->parm_buf = param; 898 rc = mCamOps->set_stream_parms(mCamHandle, 899 mChannelHandle, 900 mHandle, 901 &mStreamInfo->parm_buf); 902 if (rc == NO_ERROR) { 903 param = mStreamInfo->parm_buf; 904 } 905 return rc; 906 } 907 908 /*=========================================================================== 909 * FUNCTION : releaseFrameData 910 * 911 * DESCRIPTION: callback function to release frame data node 912 * 913 * PARAMETERS : 914 * @data : ptr to post process input data 915 * @user_data : user data ptr (QCameraReprocessor) 916 * 917 * RETURN : None 918 *==========================================================================*/ 919 void QCamera3Stream::releaseFrameData(void *data, void *user_data) 920 { 921 QCamera3Stream *pme = (QCamera3Stream *)user_data; 922 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data; 923 if (NULL != pme) { 924 pme->bufDone(frame->bufs[0]->buf_idx); 925 } 926 } 927 928 }; // namespace qcamera 929