StreamingProcessor.cpp revision 549e735c2ca22d16eea32fda418ba80da32a8558
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2-StreamingProcessor" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20//#define LOG_NNDEBUG 0 // Per-frame verbose logging 21 22#ifdef LOG_NNDEBUG 23#define ALOGVV(...) ALOGV(__VA_ARGS__) 24#else 25#define ALOGVV(...) ((void)0) 26#endif 27 28#include <utils/Log.h> 29#include <utils/Trace.h> 30#include <gui/BufferItem.h> 31#include <gui/Surface.h> 32#include <media/hardware/MetadataBufferType.h> 33 34#include "common/CameraDeviceBase.h" 35#include "api1/Camera2Client.h" 36#include "api1/client2/StreamingProcessor.h" 37#include "api1/client2/Camera2Heap.h" 38 39namespace android { 40namespace camera2 { 41 42StreamingProcessor::StreamingProcessor(sp<Camera2Client> client): 43 mClient(client), 44 mDevice(client->getCameraDevice()), 45 mId(client->getCameraId()), 46 mActiveRequest(NONE), 47 mPaused(false), 48 mPreviewRequestId(Camera2Client::kPreviewRequestIdStart), 49 mPreviewStreamId(NO_STREAM), 50 mRecordingRequestId(Camera2Client::kRecordingRequestIdStart), 51 mRecordingStreamId(NO_STREAM), 52 mRecordingFrameAvailable(false), 53 mRecordingHeapCount(kDefaultRecordingHeapCount), 54 mRecordingHeapFree(kDefaultRecordingHeapCount) 55{ 56} 57 58StreamingProcessor::~StreamingProcessor() { 59 deletePreviewStream(); 60 deleteRecordingStream(); 61} 62 63status_t StreamingProcessor::setPreviewWindow(sp<ANativeWindow> window) { 64 ATRACE_CALL(); 65 status_t res; 66 67 res = deletePreviewStream(); 68 if (res != OK) return res; 69 70 Mutex::Autolock m(mMutex); 71 72 mPreviewWindow = window; 73 74 return OK; 75} 76 77bool StreamingProcessor::haveValidPreviewWindow() const { 78 Mutex::Autolock m(mMutex); 79 return mPreviewWindow != 0; 80} 81 82status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { 83 ATRACE_CALL(); 84 status_t res; 85 sp<CameraDeviceBase> device = mDevice.promote(); 86 if (device == 0) { 87 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 88 return INVALID_OPERATION; 89 } 90 91 Mutex::Autolock m(mMutex); 92 if (mPreviewRequest.entryCount() == 0) { 93 sp<Camera2Client> client = mClient.promote(); 94 if (client == 0) { 95 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 96 return INVALID_OPERATION; 97 } 98 99 // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case. 100 if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) { 101 if (params.zslMode && !params.recordingHint) { 102 res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, 103 &mPreviewRequest); 104 } else { 105 res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW, 106 &mPreviewRequest); 107 } 108 } else { 109 res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 110 &mPreviewRequest); 111 } 112 113 if (res != OK) { 114 ALOGE("%s: Camera %d: Unable to create default preview request: " 115 "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 116 return res; 117 } 118 } 119 120 res = params.updateRequest(&mPreviewRequest); 121 if (res != OK) { 122 ALOGE("%s: Camera %d: Unable to update common entries of preview " 123 "request: %s (%d)", __FUNCTION__, mId, 124 strerror(-res), res); 125 return res; 126 } 127 128 res = mPreviewRequest.update(ANDROID_REQUEST_ID, 129 &mPreviewRequestId, 1); 130 if (res != OK) { 131 ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)", 132 __FUNCTION__, mId, strerror(-res), res); 133 return res; 134 } 135 136 return OK; 137} 138 139status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { 140 ATRACE_CALL(); 141 Mutex::Autolock m(mMutex); 142 143 status_t res; 144 sp<CameraDeviceBase> device = mDevice.promote(); 145 if (device == 0) { 146 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 147 return INVALID_OPERATION; 148 } 149 150 if (mPreviewStreamId != NO_STREAM) { 151 // Check if stream parameters have to change 152 uint32_t currentWidth, currentHeight; 153 res = device->getStreamInfo(mPreviewStreamId, 154 ¤tWidth, ¤tHeight, 0); 155 if (res != OK) { 156 ALOGE("%s: Camera %d: Error querying preview stream info: " 157 "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 158 return res; 159 } 160 if (currentWidth != (uint32_t)params.previewWidth || 161 currentHeight != (uint32_t)params.previewHeight) { 162 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d", 163 __FUNCTION__, mId, currentWidth, currentHeight, 164 params.previewWidth, params.previewHeight); 165 res = device->waitUntilDrained(); 166 if (res != OK) { 167 ALOGE("%s: Camera %d: Error waiting for preview to drain: " 168 "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 169 return res; 170 } 171 res = device->deleteStream(mPreviewStreamId); 172 if (res != OK) { 173 ALOGE("%s: Camera %d: Unable to delete old output stream " 174 "for preview: %s (%d)", __FUNCTION__, mId, 175 strerror(-res), res); 176 return res; 177 } 178 mPreviewStreamId = NO_STREAM; 179 } 180 } 181 182 if (mPreviewStreamId == NO_STREAM) { 183 res = device->createStream(mPreviewWindow, 184 params.previewWidth, params.previewHeight, 185 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN, 186 &mPreviewStreamId); 187 if (res != OK) { 188 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)", 189 __FUNCTION__, mId, strerror(-res), res); 190 return res; 191 } 192 } 193 194 res = device->setStreamTransform(mPreviewStreamId, 195 params.previewTransform); 196 if (res != OK) { 197 ALOGE("%s: Camera %d: Unable to set preview stream transform: " 198 "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 199 return res; 200 } 201 202 return OK; 203} 204 205status_t StreamingProcessor::deletePreviewStream() { 206 ATRACE_CALL(); 207 status_t res; 208 209 Mutex::Autolock m(mMutex); 210 211 if (mPreviewStreamId != NO_STREAM) { 212 sp<CameraDeviceBase> device = mDevice.promote(); 213 if (device == 0) { 214 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 215 return INVALID_OPERATION; 216 } 217 218 ALOGV("%s: for cameraId %d on streamId %d", 219 __FUNCTION__, mId, mPreviewStreamId); 220 221 res = device->waitUntilDrained(); 222 if (res != OK) { 223 ALOGE("%s: Error waiting for preview to drain: %s (%d)", 224 __FUNCTION__, strerror(-res), res); 225 return res; 226 } 227 res = device->deleteStream(mPreviewStreamId); 228 if (res != OK) { 229 ALOGE("%s: Unable to delete old preview stream: %s (%d)", 230 __FUNCTION__, strerror(-res), res); 231 return res; 232 } 233 mPreviewStreamId = NO_STREAM; 234 } 235 return OK; 236} 237 238int StreamingProcessor::getPreviewStreamId() const { 239 Mutex::Autolock m(mMutex); 240 return mPreviewStreamId; 241} 242 243status_t StreamingProcessor::setRecordingBufferCount(size_t count) { 244 ATRACE_CALL(); 245 // Make sure we can support this many buffer slots 246 if (count > BufferQueue::NUM_BUFFER_SLOTS) { 247 ALOGE("%s: Camera %d: Too many recording buffers requested: %zu, max %d", 248 __FUNCTION__, mId, count, BufferQueue::NUM_BUFFER_SLOTS); 249 return BAD_VALUE; 250 } 251 252 Mutex::Autolock m(mMutex); 253 254 ALOGV("%s: Camera %d: New recording buffer count from encoder: %zu", 255 __FUNCTION__, mId, count); 256 257 // Need to re-size consumer and heap 258 if (mRecordingHeapCount != count) { 259 ALOGV("%s: Camera %d: Resetting recording heap and consumer", 260 __FUNCTION__, mId); 261 262 if (isStreamActive(mActiveStreamIds, mRecordingStreamId)) { 263 ALOGE("%s: Camera %d: Setting recording buffer count when " 264 "recording stream is already active!", __FUNCTION__, 265 mId); 266 return INVALID_OPERATION; 267 } 268 269 releaseAllRecordingFramesLocked(); 270 271 if (mRecordingHeap != 0) { 272 mRecordingHeap.clear(); 273 } 274 mRecordingHeapCount = count; 275 mRecordingHeapFree = count; 276 277 mRecordingConsumer.clear(); 278 } 279 280 return OK; 281} 282 283status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { 284 ATRACE_CALL(); 285 status_t res; 286 Mutex::Autolock m(mMutex); 287 288 sp<CameraDeviceBase> device = mDevice.promote(); 289 if (device == 0) { 290 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 291 return INVALID_OPERATION; 292 } 293 294 if (mRecordingRequest.entryCount() == 0) { 295 res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD, 296 &mRecordingRequest); 297 if (res != OK) { 298 ALOGE("%s: Camera %d: Unable to create default recording request:" 299 " %s (%d)", __FUNCTION__, mId, strerror(-res), res); 300 return res; 301 } 302 } 303 304 res = params.updateRequest(&mRecordingRequest); 305 if (res != OK) { 306 ALOGE("%s: Camera %d: Unable to update common entries of recording " 307 "request: %s (%d)", __FUNCTION__, mId, 308 strerror(-res), res); 309 return res; 310 } 311 312 res = mRecordingRequest.update(ANDROID_REQUEST_ID, 313 &mRecordingRequestId, 1); 314 if (res != OK) { 315 ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)", 316 __FUNCTION__, mId, strerror(-res), res); 317 return res; 318 } 319 320 return OK; 321} 322 323status_t StreamingProcessor::recordingStreamNeedsUpdate( 324 const Parameters ¶ms, bool *needsUpdate) { 325 status_t res; 326 327 if (needsUpdate == 0) { 328 ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId); 329 return INVALID_OPERATION; 330 } 331 332 if (mRecordingStreamId == NO_STREAM) { 333 *needsUpdate = true; 334 return OK; 335 } 336 337 sp<CameraDeviceBase> device = mDevice.promote(); 338 if (device == 0) { 339 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 340 return INVALID_OPERATION; 341 } 342 343 uint32_t currentWidth, currentHeight; 344 res = device->getStreamInfo(mRecordingStreamId, 345 ¤tWidth, ¤tHeight, 0); 346 if (res != OK) { 347 ALOGE("%s: Camera %d: Error querying recording output stream info: " 348 "%s (%d)", __FUNCTION__, mId, 349 strerror(-res), res); 350 return res; 351 } 352 353 if (mRecordingConsumer == 0 || currentWidth != (uint32_t)params.videoWidth || 354 currentHeight != (uint32_t)params.videoHeight) { 355 *needsUpdate = true; 356 } 357 *needsUpdate = false; 358 return res; 359} 360 361status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { 362 ATRACE_CALL(); 363 status_t res; 364 Mutex::Autolock m(mMutex); 365 366 sp<CameraDeviceBase> device = mDevice.promote(); 367 if (device == 0) { 368 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 369 return INVALID_OPERATION; 370 } 371 372 bool newConsumer = false; 373 if (mRecordingConsumer == 0) { 374 ALOGV("%s: Camera %d: Creating recording consumer with %zu + 1 " 375 "consumer-side buffers", __FUNCTION__, mId, mRecordingHeapCount); 376 // Create CPU buffer queue endpoint. We need one more buffer here so that we can 377 // always acquire and free a buffer when the heap is full; otherwise the consumer 378 // will have buffers in flight we'll never clear out. 379 sp<IGraphicBufferProducer> producer; 380 sp<IGraphicBufferConsumer> consumer; 381 BufferQueue::createBufferQueue(&producer, &consumer); 382 mRecordingConsumer = new BufferItemConsumer(consumer, 383 GRALLOC_USAGE_HW_VIDEO_ENCODER, 384 mRecordingHeapCount + 1); 385 mRecordingConsumer->setFrameAvailableListener(this); 386 mRecordingConsumer->setName(String8("Camera2-RecordingConsumer")); 387 mRecordingWindow = new Surface(producer); 388 newConsumer = true; 389 // Allocate memory later, since we don't know buffer size until receipt 390 } 391 392 if (mRecordingStreamId != NO_STREAM) { 393 // Check if stream parameters have to change 394 uint32_t currentWidth, currentHeight; 395 res = device->getStreamInfo(mRecordingStreamId, 396 ¤tWidth, ¤tHeight, 0); 397 if (res != OK) { 398 ALOGE("%s: Camera %d: Error querying recording output stream info: " 399 "%s (%d)", __FUNCTION__, mId, 400 strerror(-res), res); 401 return res; 402 } 403 if (currentWidth != (uint32_t)params.videoWidth || 404 currentHeight != (uint32_t)params.videoHeight || newConsumer) { 405 // TODO: Should wait to be sure previous recording has finished 406 res = device->deleteStream(mRecordingStreamId); 407 408 if (res == -EBUSY) { 409 ALOGV("%s: Camera %d: Device is busy, call " 410 "updateRecordingStream after it becomes idle", 411 __FUNCTION__, mId); 412 return res; 413 } else if (res != OK) { 414 ALOGE("%s: Camera %d: Unable to delete old output stream " 415 "for recording: %s (%d)", __FUNCTION__, 416 mId, strerror(-res), res); 417 return res; 418 } 419 mRecordingStreamId = NO_STREAM; 420 } 421 } 422 423 if (mRecordingStreamId == NO_STREAM) { 424 mRecordingFrameCount = 0; 425 // Selecting BT.709 colorspace by default 426 // TODO: Wire this in from encoder side 427 res = device->createStream(mRecordingWindow, 428 params.videoWidth, params.videoHeight, 429 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 430 HAL_DATASPACE_BT709, &mRecordingStreamId); 431 if (res != OK) { 432 ALOGE("%s: Camera %d: Can't create output stream for recording: " 433 "%s (%d)", __FUNCTION__, mId, 434 strerror(-res), res); 435 return res; 436 } 437 } 438 439 return OK; 440} 441 442status_t StreamingProcessor::deleteRecordingStream() { 443 ATRACE_CALL(); 444 status_t res; 445 446 Mutex::Autolock m(mMutex); 447 448 if (mRecordingStreamId != NO_STREAM) { 449 sp<CameraDeviceBase> device = mDevice.promote(); 450 if (device == 0) { 451 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 452 return INVALID_OPERATION; 453 } 454 455 res = device->waitUntilDrained(); 456 if (res != OK) { 457 ALOGE("%s: Error waiting for HAL to drain: %s (%d)", 458 __FUNCTION__, strerror(-res), res); 459 return res; 460 } 461 res = device->deleteStream(mRecordingStreamId); 462 if (res != OK) { 463 ALOGE("%s: Unable to delete recording stream: %s (%d)", 464 __FUNCTION__, strerror(-res), res); 465 return res; 466 } 467 mRecordingStreamId = NO_STREAM; 468 } 469 return OK; 470} 471 472int StreamingProcessor::getRecordingStreamId() const { 473 return mRecordingStreamId; 474} 475 476status_t StreamingProcessor::startStream(StreamType type, 477 const Vector<int32_t> &outputStreams) { 478 ATRACE_CALL(); 479 status_t res; 480 481 if (type == NONE) return INVALID_OPERATION; 482 483 sp<CameraDeviceBase> device = mDevice.promote(); 484 if (device == 0) { 485 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 486 return INVALID_OPERATION; 487 } 488 489 ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type); 490 491 Mutex::Autolock m(mMutex); 492 493 // If a recording stream is being started up and no recording 494 // stream is active yet, free up any outstanding buffers left 495 // from the previous recording session. There should never be 496 // any, so if there are, warn about it. 497 bool isRecordingStreamIdle = !isStreamActive(mActiveStreamIds, mRecordingStreamId); 498 bool startRecordingStream = isStreamActive(outputStreams, mRecordingStreamId); 499 if (startRecordingStream && isRecordingStreamIdle) { 500 releaseAllRecordingFramesLocked(); 501 } 502 503 ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu", 504 __FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording", 505 mRecordingHeapFree, mRecordingHeapCount); 506 507 CameraMetadata &request = (type == PREVIEW) ? 508 mPreviewRequest : mRecordingRequest; 509 510 res = request.update( 511 ANDROID_REQUEST_OUTPUT_STREAMS, 512 outputStreams); 513 if (res != OK) { 514 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)", 515 __FUNCTION__, mId, strerror(-res), res); 516 return res; 517 } 518 519 res = request.sort(); 520 if (res != OK) { 521 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)", 522 __FUNCTION__, mId, strerror(-res), res); 523 return res; 524 } 525 526 res = device->setStreamingRequest(request); 527 if (res != OK) { 528 ALOGE("%s: Camera %d: Unable to set preview request to start preview: " 529 "%s (%d)", 530 __FUNCTION__, mId, strerror(-res), res); 531 return res; 532 } 533 mActiveRequest = type; 534 mPaused = false; 535 mActiveStreamIds = outputStreams; 536 return OK; 537} 538 539status_t StreamingProcessor::togglePauseStream(bool pause) { 540 ATRACE_CALL(); 541 status_t res; 542 543 sp<CameraDeviceBase> device = mDevice.promote(); 544 if (device == 0) { 545 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 546 return INVALID_OPERATION; 547 } 548 549 ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause); 550 551 Mutex::Autolock m(mMutex); 552 553 if (mActiveRequest == NONE) { 554 ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started", 555 __FUNCTION__, mId); 556 return INVALID_OPERATION; 557 } 558 559 if (mPaused == pause) { 560 return OK; 561 } 562 563 if (pause) { 564 res = device->clearStreamingRequest(); 565 if (res != OK) { 566 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 567 __FUNCTION__, mId, strerror(-res), res); 568 return res; 569 } 570 } else { 571 CameraMetadata &request = 572 (mActiveRequest == PREVIEW) ? mPreviewRequest 573 : mRecordingRequest; 574 res = device->setStreamingRequest(request); 575 if (res != OK) { 576 ALOGE("%s: Camera %d: Unable to set preview request to resume: " 577 "%s (%d)", 578 __FUNCTION__, mId, strerror(-res), res); 579 return res; 580 } 581 } 582 583 mPaused = pause; 584 return OK; 585} 586 587status_t StreamingProcessor::stopStream() { 588 ATRACE_CALL(); 589 status_t res; 590 591 Mutex::Autolock m(mMutex); 592 593 sp<CameraDeviceBase> device = mDevice.promote(); 594 if (device == 0) { 595 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 596 return INVALID_OPERATION; 597 } 598 599 res = device->clearStreamingRequest(); 600 if (res != OK) { 601 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 602 __FUNCTION__, mId, strerror(-res), res); 603 return res; 604 } 605 606 mActiveRequest = NONE; 607 mActiveStreamIds.clear(); 608 mPaused = false; 609 610 return OK; 611} 612 613int32_t StreamingProcessor::getActiveRequestId() const { 614 Mutex::Autolock m(mMutex); 615 switch (mActiveRequest) { 616 case NONE: 617 return 0; 618 case PREVIEW: 619 return mPreviewRequestId; 620 case RECORD: 621 return mRecordingRequestId; 622 default: 623 ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest); 624 return 0; 625 } 626} 627 628status_t StreamingProcessor::incrementStreamingIds() { 629 ATRACE_CALL(); 630 Mutex::Autolock m(mMutex); 631 632 mPreviewRequestId++; 633 if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) { 634 mPreviewRequestId = Camera2Client::kPreviewRequestIdStart; 635 } 636 mRecordingRequestId++; 637 if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) { 638 mRecordingRequestId = Camera2Client::kRecordingRequestIdStart; 639 } 640 return OK; 641} 642 643void StreamingProcessor::onFrameAvailable(const BufferItem& /*item*/) { 644 ATRACE_CALL(); 645 Mutex::Autolock l(mMutex); 646 if (!mRecordingFrameAvailable) { 647 mRecordingFrameAvailable = true; 648 mRecordingFrameAvailableSignal.signal(); 649 } 650 651} 652 653bool StreamingProcessor::threadLoop() { 654 status_t res; 655 656 { 657 Mutex::Autolock l(mMutex); 658 while (!mRecordingFrameAvailable) { 659 res = mRecordingFrameAvailableSignal.waitRelative( 660 mMutex, kWaitDuration); 661 if (res == TIMED_OUT) return true; 662 } 663 mRecordingFrameAvailable = false; 664 } 665 666 do { 667 res = processRecordingFrame(); 668 } while (res == OK); 669 670 return true; 671} 672 673status_t StreamingProcessor::processRecordingFrame() { 674 ATRACE_CALL(); 675 status_t res; 676 sp<Camera2Heap> recordingHeap; 677 size_t heapIdx = 0; 678 nsecs_t timestamp; 679 680 sp<Camera2Client> client = mClient.promote(); 681 if (client == 0) { 682 // Discard frames during shutdown 683 BufferItem imgBuffer; 684 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0); 685 if (res != OK) { 686 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 687 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", 688 __FUNCTION__, mId, strerror(-res), res); 689 } 690 return res; 691 } 692 mRecordingConsumer->releaseBuffer(imgBuffer); 693 return OK; 694 } 695 696 { 697 /* acquire SharedParameters before mMutex so we don't dead lock 698 with Camera2Client code calling into StreamingProcessor */ 699 SharedParameters::Lock l(client->getParameters()); 700 Mutex::Autolock m(mMutex); 701 BufferItem imgBuffer; 702 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0); 703 if (res != OK) { 704 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 705 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", 706 __FUNCTION__, mId, strerror(-res), res); 707 } 708 return res; 709 } 710 timestamp = imgBuffer.mTimestamp; 711 712 mRecordingFrameCount++; 713 ALOGVV("OnRecordingFrame: Frame %d", mRecordingFrameCount); 714 715 if (l.mParameters.state != Parameters::RECORD && 716 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { 717 ALOGV("%s: Camera %d: Discarding recording image buffers " 718 "received after recording done", __FUNCTION__, 719 mId); 720 mRecordingConsumer->releaseBuffer(imgBuffer); 721 return INVALID_OPERATION; 722 } 723 724 if (mRecordingHeap == 0) { 725 const size_t bufferSize = 4 + sizeof(buffer_handle_t); 726 ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of " 727 "size %zu bytes", __FUNCTION__, mId, 728 mRecordingHeapCount, bufferSize); 729 730 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount, 731 "Camera2Client::RecordingHeap"); 732 if (mRecordingHeap->mHeap->getSize() == 0) { 733 ALOGE("%s: Camera %d: Unable to allocate memory for recording", 734 __FUNCTION__, mId); 735 mRecordingConsumer->releaseBuffer(imgBuffer); 736 return NO_MEMORY; 737 } 738 for (size_t i = 0; i < mRecordingBuffers.size(); i++) { 739 if (mRecordingBuffers[i].mBuf != 740 BufferItemConsumer::INVALID_BUFFER_SLOT) { 741 ALOGE("%s: Camera %d: Non-empty recording buffers list!", 742 __FUNCTION__, mId); 743 } 744 } 745 mRecordingBuffers.clear(); 746 mRecordingBuffers.setCapacity(mRecordingHeapCount); 747 mRecordingBuffers.insertAt(0, mRecordingHeapCount); 748 749 mRecordingHeapHead = 0; 750 mRecordingHeapFree = mRecordingHeapCount; 751 } 752 753 if ( mRecordingHeapFree == 0) { 754 ALOGE("%s: Camera %d: No free recording buffers, dropping frame", 755 __FUNCTION__, mId); 756 mRecordingConsumer->releaseBuffer(imgBuffer); 757 return NO_MEMORY; 758 } 759 760 heapIdx = mRecordingHeapHead; 761 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount; 762 mRecordingHeapFree--; 763 764 ALOGVV("%s: Camera %d: Timestamp %lld", 765 __FUNCTION__, mId, timestamp); 766 767 ssize_t offset; 768 size_t size; 769 sp<IMemoryHeap> heap = 770 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset, 771 &size); 772 773 uint8_t *data = (uint8_t*)heap->getBase() + offset; 774 uint32_t type = kMetadataBufferTypeGrallocSource; 775 *((uint32_t*)data) = type; 776 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle; 777 ALOGVV("%s: Camera %d: Sending out buffer_handle_t %p", 778 __FUNCTION__, mId, 779 imgBuffer.mGraphicBuffer->handle); 780 mRecordingBuffers.replaceAt(imgBuffer, heapIdx); 781 recordingHeap = mRecordingHeap; 782 } 783 784 // Call outside locked parameters to allow re-entrancy from notification 785 Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks); 786 if (l.mRemoteCallback != 0) { 787 l.mRemoteCallback->dataCallbackTimestamp(timestamp, 788 CAMERA_MSG_VIDEO_FRAME, 789 recordingHeap->mBuffers[heapIdx]); 790 } else { 791 ALOGW("%s: Camera %d: Remote callback gone", __FUNCTION__, mId); 792 } 793 794 return OK; 795} 796 797void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { 798 ATRACE_CALL(); 799 status_t res; 800 801 Mutex::Autolock m(mMutex); 802 // Make sure this is for the current heap 803 ssize_t offset; 804 size_t size; 805 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 806 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) { 807 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release " 808 "(got %x, expected %x)", __FUNCTION__, mId, 809 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID()); 810 return; 811 } 812 uint8_t *data = (uint8_t*)heap->getBase() + offset; 813 uint32_t type = *(uint32_t*)data; 814 if (type != kMetadataBufferTypeGrallocSource) { 815 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)", 816 __FUNCTION__, mId, type, 817 kMetadataBufferTypeGrallocSource); 818 return; 819 } 820 821 // Release the buffer back to the recording queue 822 823 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4); 824 825 size_t itemIndex; 826 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 827 const BufferItem item = mRecordingBuffers[itemIndex]; 828 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT && 829 item.mGraphicBuffer->handle == imgHandle) { 830 break; 831 } 832 } 833 if (itemIndex == mRecordingBuffers.size()) { 834 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of " 835 "outstanding buffers", __FUNCTION__, mId, 836 imgHandle); 837 return; 838 } 839 840 ALOGVV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, 841 mId, imgHandle); 842 843 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 844 if (res != OK) { 845 ALOGE("%s: Camera %d: Unable to free recording frame " 846 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 847 mId, imgHandle, strerror(-res), res); 848 return; 849 } 850 mRecordingBuffers.replaceAt(itemIndex); 851 852 mRecordingHeapFree++; 853 ALOGV_IF(mRecordingHeapFree == mRecordingHeapCount, 854 "%s: Camera %d: All %d recording buffers returned", 855 __FUNCTION__, mId, mRecordingHeapCount); 856} 857 858void StreamingProcessor::releaseAllRecordingFramesLocked() { 859 ATRACE_CALL(); 860 status_t res; 861 862 if (mRecordingConsumer == 0) { 863 return; 864 } 865 866 ALOGV("%s: Camera %d: Releasing all recording buffers", __FUNCTION__, 867 mId); 868 869 size_t releasedCount = 0; 870 for (size_t itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 871 const BufferItem item = mRecordingBuffers[itemIndex]; 872 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) { 873 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 874 if (res != OK) { 875 ALOGE("%s: Camera %d: Unable to free recording frame " 876 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 877 mId, item.mGraphicBuffer->handle, strerror(-res), res); 878 } 879 mRecordingBuffers.replaceAt(itemIndex); 880 releasedCount++; 881 } 882 } 883 884 if (releasedCount > 0) { 885 ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers " 886 "from previous recording session", __FUNCTION__, mId, releasedCount); 887 ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree, 888 "%s: Camera %d: Force-freed %zu buffers, but expected %zu", 889 __FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree); 890 } 891 892 mRecordingHeapHead = 0; 893 mRecordingHeapFree = mRecordingHeapCount; 894} 895 896bool StreamingProcessor::isStreamActive(const Vector<int32_t> &streams, 897 int32_t recordingStreamId) { 898 for (size_t i = 0; i < streams.size(); i++) { 899 if (streams[i] == recordingStreamId) { 900 return true; 901 } 902 } 903 return false; 904} 905 906 907status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) { 908 String8 result; 909 910 result.append(" Current requests:\n"); 911 if (mPreviewRequest.entryCount() != 0) { 912 result.append(" Preview request:\n"); 913 write(fd, result.string(), result.size()); 914 mPreviewRequest.dump(fd, 2, 6); 915 result.clear(); 916 } else { 917 result.append(" Preview request: undefined\n"); 918 } 919 920 if (mRecordingRequest.entryCount() != 0) { 921 result = " Recording request:\n"; 922 write(fd, result.string(), result.size()); 923 mRecordingRequest.dump(fd, 2, 6); 924 result.clear(); 925 } else { 926 result = " Recording request: undefined\n"; 927 } 928 929 const char* streamTypeString[] = { 930 "none", "preview", "record" 931 }; 932 result.append(String8::format(" Active request: %s (paused: %s)\n", 933 streamTypeString[mActiveRequest], 934 mPaused ? "yes" : "no")); 935 936 write(fd, result.string(), result.size()); 937 938 return OK; 939} 940 941}; // namespace camera2 942}; // namespace android 943