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