QCamera3Channel.cpp revision 9de643761e1282fb5af14a9249618efa9d8ac8fe
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 <hardware/camera3.h> 33#include <gralloc_priv.h> 34#include <utils/Log.h> 35#include <utils/Errors.h> 36#include "QCamera3Channel.h" 37 38using namespace android; 39 40#define MIN_STREAMING_BUFFER_NUM 3 41 42namespace qcamera { 43 44/*=========================================================================== 45 * FUNCTION : QCamera3Channel 46 * 47 * DESCRIPTION: constrcutor of QCamera3Channel 48 * 49 * PARAMETERS : 50 * @cam_handle : camera handle 51 * @cam_ops : ptr to camera ops table 52 * 53 * RETURN : none 54 *==========================================================================*/ 55QCamera3Channel::QCamera3Channel(uint32_t cam_handle, 56 mm_camera_ops_t *cam_ops, 57 channel_cb_routine cb_routine) 58{ 59 m_camHandle = cam_handle; 60 m_camOps = cam_ops; 61 mChannelCB = cb_routine; 62 m_bIsActive = false; 63 64 m_handle = 0; 65 m_numStreams = 0; 66 memset(mStreams, 0, sizeof(mStreams)); 67} 68 69/*=========================================================================== 70 * FUNCTION : QCamera3Channel 71 * 72 * DESCRIPTION: default constrcutor of QCamera3Channel 73 * 74 * PARAMETERS : none 75 * 76 * RETURN : none 77 *==========================================================================*/ 78QCamera3Channel::QCamera3Channel() 79{ 80 m_camHandle = 0; 81 m_camOps = NULL; 82 m_bIsActive = false; 83 84 m_handle = 0; 85 m_numStreams = 0; 86 memset(mStreams, 0, sizeof(mStreams)); 87} 88 89/*=========================================================================== 90 * FUNCTION : ~QCamera3Channel 91 * 92 * DESCRIPTION: destructor of QCamera3Channel 93 * 94 * PARAMETERS : none 95 * 96 * RETURN : none 97 *==========================================================================*/ 98QCamera3Channel::~QCamera3Channel() 99{ 100 if (m_bIsActive) { 101 stop(); 102 } 103 104 for (int i = 0; i < m_numStreams; i++) { 105 if (mStreams[i] != NULL) { 106 delete mStreams[i]; 107 mStreams[i] = 0; 108 } 109 } 110 m_numStreams = 0; 111 m_camOps->delete_channel(m_camHandle, m_handle); 112 m_handle = 0; 113} 114 115/*=========================================================================== 116 * FUNCTION : init 117 * 118 * DESCRIPTION: initialization of channel 119 * 120 * PARAMETERS : 121 * @attr : channel bundle attribute setting 122 * @dataCB : data notify callback 123 * @userData: user data ptr 124 * 125 * RETURN : int32_t type of status 126 * NO_ERROR -- success 127 * none-zero failure code 128 *==========================================================================*/ 129int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr, 130 mm_camera_buf_notify_t dataCB, 131 cam_padding_info_t *paddingInfo, 132 void *userData) 133{ 134 m_handle = m_camOps->add_channel(m_camHandle, 135 attr, 136 dataCB, 137 userData); 138 if (m_handle == 0) { 139 ALOGE("%s: Add channel failed", __func__); 140 return UNKNOWN_ERROR; 141 } 142 mPaddingInfo = paddingInfo; 143 mUserData = userData; 144 return NO_ERROR; 145} 146 147/*=========================================================================== 148 * FUNCTION : addStream 149 * 150 * DESCRIPTION: add a stream into channel 151 * 152 * PARAMETERS : 153 * @allocator : stream related buffer allocator 154 * @streamInfoBuf : ptr to buf that constains stream info 155 * @minStreamBufNum: number of stream buffers needed 156 * @paddingInfo : padding information 157 * @stream_cb : stream data notify callback 158 * @userdata : user data ptr 159 * 160 * RETURN : int32_t type of status 161 * NO_ERROR -- success 162 * none-zero failure code 163 *==========================================================================*/ 164int32_t QCamera3Channel::addStream(cam_stream_type_t streamType, 165 cam_format_t streamFormat, 166 cam_dimension_t streamDim, 167 uint8_t minStreamBufNum, 168 cam_padding_info_t *paddingInfo) 169{ 170 int32_t rc = NO_ERROR; 171 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) { 172 ALOGE("%s: stream number (%d) exceeds max limit (%d)", 173 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE); 174 return BAD_VALUE; 175 } 176 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 177 m_handle, 178 m_camOps, 179 paddingInfo, 180 this); 181 if (pStream == NULL) { 182 ALOGE("%s: No mem for Stream", __func__); 183 return NO_MEMORY; 184 } 185 186 rc = pStream->init(streamType, streamFormat, streamDim, minStreamBufNum, streamCbRoutine, this); 187 if (rc == 0) { 188 mStreams[m_numStreams] = pStream; 189 m_numStreams++; 190 } else { 191 delete pStream; 192 } 193 return rc; 194} 195 196/*=========================================================================== 197 * FUNCTION : start 198 * 199 * DESCRIPTION: start channel, which will start all streams belong to this channel 200 * 201 * PARAMETERS : 202 * 203 * RETURN : int32_t type of status 204 * NO_ERROR -- success 205 * none-zero failure code 206 *==========================================================================*/ 207int32_t QCamera3Channel::start() 208{ 209 int32_t rc = NO_ERROR; 210 211 if (m_numStreams > 1) { 212 ALOGE("%s: bundle not supported", __func__); 213 } 214 215 for (int i = 0; i < m_numStreams; i++) { 216 if (mStreams[i] != NULL) { 217 mStreams[i]->start(); 218 } 219 } 220 rc = m_camOps->start_channel(m_camHandle, m_handle); 221 222 if (rc != NO_ERROR) { 223 for (int i = 0; i < m_numStreams; i++) { 224 if (mStreams[i] != NULL) { 225 mStreams[i]->stop(); 226 } 227 } 228 } else { 229 m_bIsActive = true; 230 } 231 232 return rc; 233} 234 235/*=========================================================================== 236 * FUNCTION : stop 237 * 238 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 239 * 240 * PARAMETERS : none 241 * 242 * RETURN : int32_t type of status 243 * NO_ERROR -- success 244 * none-zero failure code 245 *==========================================================================*/ 246int32_t QCamera3Channel::stop() 247{ 248 int32_t rc = NO_ERROR; 249 rc = m_camOps->stop_channel(m_camHandle, m_handle); 250 251 for (int i = 0; i < m_numStreams; i++) { 252 if (mStreams[i] != NULL) { 253 mStreams[i]->stop(); 254 } 255 } 256 257 m_bIsActive = false; 258 return rc; 259} 260 261/*=========================================================================== 262 * FUNCTION : bufDone 263 * 264 * DESCRIPTION: return a stream buf back to kernel 265 * 266 * PARAMETERS : 267 * @recvd_frame : stream buf frame to be returned 268 * 269 * RETURN : int32_t type of status 270 * NO_ERROR -- success 271 * none-zero failure code 272 *==========================================================================*/ 273int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame) 274{ 275 int32_t rc = NO_ERROR; 276 for (int i = 0; i < recvd_frame->num_bufs; i++) { 277 if (recvd_frame->bufs[i] != NULL) { 278 for (int j = 0; j < m_numStreams; j++) { 279 if (mStreams[j] != NULL && 280 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 281 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 282 break; // break loop j 283 } 284 } 285 } 286 } 287 288 return rc; 289} 290 291/*=========================================================================== 292 * FUNCTION : getStreamByHandle 293 * 294 * DESCRIPTION: return stream object by stream handle 295 * 296 * PARAMETERS : 297 * @streamHandle : stream handle 298 * 299 * RETURN : stream object. NULL if not found 300 *==========================================================================*/ 301QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle) 302{ 303 for (int i = 0; i < m_numStreams; i++) { 304 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 305 return mStreams[i]; 306 } 307 } 308 return NULL; 309} 310 311/*=========================================================================== 312 * FUNCTION : getStreamByHandle 313 * 314 * DESCRIPTION: return stream object by stream handle 315 * 316 * PARAMETERS : 317 * @streamHandle : stream handle 318 * 319 * RETURN : stream object. NULL if not found 320 *==========================================================================*/ 321QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index) 322{ 323 if (index < m_numStreams) { 324 return mStreams[index]; 325 } 326 return NULL; 327} 328 329/*=========================================================================== 330 * FUNCTION : streamCbRoutine 331 * 332 * DESCRIPTION: callback routine for stream 333 * 334 * PARAMETERS : 335 * @streamHandle : stream handle 336 * 337 * RETURN : stream object. NULL if not found 338 *==========================================================================*/ 339void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 340 QCamera3Stream *stream, void *userdata) 341{ 342 QCamera3Channel *channel = (QCamera3Channel *)userdata; 343 if (channel == NULL) { 344 ALOGE("%s: invalid channel pointer", __func__); 345 return; 346 } 347 channel->streamCbRoutine(super_frame, stream); 348} 349 350/*=========================================================================== 351 * FUNCTION : QCamera3RegularChannel 352 * 353 * DESCRIPTION: constrcutor of QCamera3RegularChannel 354 * 355 * PARAMETERS : 356 * @cam_handle : camera handle 357 * @cam_ops : ptr to camera ops table 358 * @cb_routine : callback routine to frame aggregator 359 * @stream : camera3_stream_t structure 360 * 361 * RETURN : none 362 *==========================================================================*/ 363QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 364 mm_camera_ops_t *cam_ops, 365 channel_cb_routine cb_routine, 366 camera3_stream_t *stream) : 367 QCamera3Channel(cam_handle, cam_ops, cb_routine), 368 mCamera3Stream(stream), 369 mNumBufs(0), 370 mCamera3Buffers(NULL), 371 mMemory(NULL) 372{ 373 //TODO 374} 375 376/*=========================================================================== 377 * FUNCTION : ~QCamera3RegularChannel 378 * 379 * DESCRIPTION: destructor of QCamera3RegularChannel 380 * 381 * PARAMETERS : none 382 * 383 * RETURN : none 384 *==========================================================================*/ 385QCamera3RegularChannel::~QCamera3RegularChannel() 386{ 387 //TODO 388} 389 390/*=========================================================================== 391 * FUNCTION : request 392 * 393 * DESCRIPTION: process a request from camera service. Stream on if ncessary. 394 * 395 * PARAMETERS : 396 * @buffer : buffer to be filled for this request 397 * 398 * RETURN : 0 on a success start of capture 399 * -EINVAL on invalid input 400 * -ENODEV on serious error 401 *==========================================================================*/ 402int32_t QCamera3RegularChannel::request(const camera3_stream_buffer_t *buffer) 403{ 404 //TODO 405 return 0; 406} 407 408/*=========================================================================== 409 * FUNCTION : registerBuffers 410 * 411 * DESCRIPTION: register streaming buffers to the channel object 412 * 413 * PARAMETERS : 414 * @num_buffers : number of buffers to be registered 415 * @buffers : buffer to be registered 416 * 417 * RETURN : 0 on a success start of capture 418 * -EINVAL on invalid input 419 * -ENOMEM on failure to register the buffer 420 * -ENODEV on serious error 421 *==========================================================================*/ 422int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 423{ 424 int rc = 0; 425 struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]); 426 cam_stream_type_t streamType; 427 cam_format_t streamFormat; 428 cam_dimension_t streamDim; 429 430 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 431 if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) { 432 streamType = CAM_STREAM_TYPE_VIDEO; 433 streamFormat = CAM_FORMAT_YUV_420_NV12; 434 } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) { 435 streamType = CAM_STREAM_TYPE_PREVIEW; 436 streamFormat = CAM_FORMAT_YUV_420_NV21; 437 } else { 438 ALOGE("%s: priv_handle->flags 0x%x not supported", 439 __func__, priv_handle->flags); 440 return -EINVAL; 441 } 442 } else { 443 //TODO: Fail for other types of streams for now 444 ALOGE("%s: format is not IMPLEMENTATION_DEFINED", __func__); 445 return -EINVAL; 446 } 447 448 mNumBufs = num_buffers; 449 mCamera3Buffers = buffers; 450 451 streamDim.width = mCamera3Stream->width; 452 streamDim.height = mCamera3Stream->height; 453 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 454 num_buffers, mPaddingInfo); 455 456 return rc; 457} 458 459void QCamera3RegularChannel::streamCbRoutine( 460 mm_camera_super_buf_t *super_frame, 461 QCamera3Stream *stream) 462{ 463 //TODO 464 return; 465} 466 467QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/) 468{ 469 int rc; 470 mMemory = new QCamera3GrallocMemory(); 471 if (mMemory == NULL) { 472 return NULL; 473 } 474 475 rc = mMemory->registerBuffers(mNumBufs, mCamera3Buffers); 476 if (rc < 0) { 477 delete mMemory; 478 mMemory = NULL; 479 return NULL; 480 } 481 return mMemory; 482} 483 484void QCamera3RegularChannel::putStreamBufs() 485{ 486 mMemory->unregisterBuffers(); 487 delete mMemory; 488 mMemory = NULL; 489} 490 491int QCamera3RegularChannel::kMaxBuffers = 3; 492 493QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle, 494 mm_camera_ops_t *cam_ops, 495 channel_cb_routine cb_routine) : 496 QCamera3Channel(cam_handle, cam_ops, cb_routine), 497 mMemory(NULL), 498 mStarted(false) 499{ 500} 501 502QCamera3MetadataChannel::~QCamera3MetadataChannel() 503{ 504 if (mStarted) 505 stop(); 506 507 if (mMemory) { 508 mMemory->deallocate(); 509 delete mMemory; 510 mMemory = NULL; 511 } 512} 513 514int32_t QCamera3MetadataChannel::initialize() 515{ 516 int32_t rc; 517 cam_dimension_t streamDim; 518 519 if (mMemory || m_numStreams > 0) { 520 ALOGE("%s: metadata channel already initialized", __func__); 521 return -EINVAL; 522 } 523 524 streamDim.width = sizeof(parm_buffer_t), 525 streamDim.height = 1; 526 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX, 527 streamDim, MIN_STREAMING_BUFFER_NUM, mPaddingInfo); 528 if (rc < 0) { 529 ALOGE("%s: addStream failed", __func__); 530 } 531 return rc; 532} 533 534int32_t QCamera3MetadataChannel::request(const camera3_stream_buffer_t *buffer) 535{ 536 if (!mStarted) 537 return start(); 538 else 539 return 0; 540} 541 542int32_t QCamera3MetadataChannel::registerBuffers(uint32_t num_buffers, 543 buffer_handle_t **buffers) 544{ 545 // no registerBuffers are supported for metadata channel 546 return -EINVAL; 547} 548 549void QCamera3MetadataChannel::streamCbRoutine( 550 mm_camera_super_buf_t *super_frame, 551 QCamera3Stream *stream) 552{ 553 if (super_frame == NULL || super_frame->num_bufs != 1) { 554 ALOGE("%s: super_frame is not valid", __func__); 555 return; 556 } 557 mChannelCB(super_frame->bufs[0], NULL, mUserData); 558} 559 560QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t /*len*/) 561{ 562 int rc; 563 mMemory = new QCamera3HeapMemory(); 564 if (!mMemory) { 565 ALOGE("%s: unable to create metadata memory", __func__); 566 return NULL; 567 } 568 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, sizeof(parm_buffer_t), true); 569 if (rc < 0) { 570 ALOGE("%s: unable to allocate metadata memory", __func__); 571 delete mMemory; 572 mMemory = NULL; 573 return NULL; 574 } 575 memset(mMemory->getPtr(0), 0, sizeof(parm_buffer_t)); 576 return mMemory; 577} 578 579void QCamera3MetadataChannel::putStreamBufs() 580{ 581 mMemory->deallocate(); 582 delete mMemory; 583 mMemory = NULL; 584} 585 586QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle, 587 mm_camera_ops_t *cam_ops, 588 channel_cb_routine cb_routine, 589 camera3_stream_t *stream) : 590 QCamera3Channel(cam_handle, cam_ops, cb_routine) 591{ 592 //TODO 593} 594 595QCamera3PicChannel::~QCamera3PicChannel() 596{ 597} 598 599int32_t QCamera3PicChannel::request(const camera3_stream_buffer_t *buffer) 600{ 601 //TODO 602 return 0; 603} 604 605int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 606 buffer_handle_t **buffers) 607{ 608 //TODO 609 return 0; 610} 611 612void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 613 QCamera3Stream *stream) 614{ 615 //TODO 616 return; 617} 618 619QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 620{ 621 int rc = 0; 622 mYuvMemory = new QCamera3HeapMemory(); 623 if (!mYuvMemory) { 624 ALOGE("%s: unable to create metadata memory", __func__); 625 return NULL; 626 } 627 628 rc = mYuvMemory->allocate(1, len, false); 629 if (rc < 0) { 630 ALOGE("%s: unable to allocate metadata memory", __func__); 631 delete mYuvMemory; 632 mYuvMemory = NULL; 633 return NULL; 634 } 635 return mYuvMemory; 636} 637 638void QCamera3PicChannel::putStreamBufs() 639{ 640 mYuvMemory->deallocate(); 641 delete mYuvMemory; 642 mYuvMemory = NULL; 643} 644 645int QCamera3PicChannel::kMaxBuffers = 1; 646}; // namespace qcamera 647