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