StreamingProcessor.cpp revision 32ce52b01dab863f2b4749e1c69f619cf820486f
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, free up any 434 // outstanding buffers left from the previous recording session. 435 // There should never be any, so if there are, warn about it. 436 if (isStreamActive(outputStreams, mRecordingStreamId)) { 437 releaseAllRecordingFramesLocked(); 438 } 439 440 ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu", 441 __FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording", 442 mRecordingHeapFree, mRecordingHeapCount); 443 444 CameraMetadata &request = (type == PREVIEW) ? 445 mPreviewRequest : mRecordingRequest; 446 447 res = request.update( 448 ANDROID_REQUEST_OUTPUT_STREAMS, 449 outputStreams); 450 if (res != OK) { 451 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)", 452 __FUNCTION__, mId, strerror(-res), res); 453 return res; 454 } 455 456 res = request.sort(); 457 if (res != OK) { 458 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)", 459 __FUNCTION__, mId, strerror(-res), res); 460 return res; 461 } 462 463 res = device->setStreamingRequest(request); 464 if (res != OK) { 465 ALOGE("%s: Camera %d: Unable to set preview request to start preview: " 466 "%s (%d)", 467 __FUNCTION__, mId, strerror(-res), res); 468 return res; 469 } 470 mActiveRequest = type; 471 mPaused = false; 472 mActiveStreamIds = outputStreams; 473 return OK; 474} 475 476status_t StreamingProcessor::togglePauseStream(bool pause) { 477 ATRACE_CALL(); 478 status_t res; 479 480 sp<CameraDeviceBase> device = mDevice.promote(); 481 if (device == 0) { 482 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 483 return INVALID_OPERATION; 484 } 485 486 ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause); 487 488 Mutex::Autolock m(mMutex); 489 490 if (mActiveRequest == NONE) { 491 ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started", 492 __FUNCTION__, mId); 493 return INVALID_OPERATION; 494 } 495 496 if (mPaused == pause) { 497 return OK; 498 } 499 500 if (pause) { 501 res = device->clearStreamingRequest(); 502 if (res != OK) { 503 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 504 __FUNCTION__, mId, strerror(-res), res); 505 return res; 506 } 507 } else { 508 CameraMetadata &request = 509 (mActiveRequest == PREVIEW) ? mPreviewRequest 510 : mRecordingRequest; 511 res = device->setStreamingRequest(request); 512 if (res != OK) { 513 ALOGE("%s: Camera %d: Unable to set preview request to resume: " 514 "%s (%d)", 515 __FUNCTION__, mId, strerror(-res), res); 516 return res; 517 } 518 } 519 520 mPaused = pause; 521 return OK; 522} 523 524status_t StreamingProcessor::stopStream() { 525 ATRACE_CALL(); 526 status_t res; 527 528 Mutex::Autolock m(mMutex); 529 530 sp<CameraDeviceBase> device = mDevice.promote(); 531 if (device == 0) { 532 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 533 return INVALID_OPERATION; 534 } 535 536 res = device->clearStreamingRequest(); 537 if (res != OK) { 538 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 539 __FUNCTION__, mId, strerror(-res), res); 540 return res; 541 } 542 543 mActiveRequest = NONE; 544 mActiveStreamIds.clear(); 545 mPaused = false; 546 547 return OK; 548} 549 550int32_t StreamingProcessor::getActiveRequestId() const { 551 Mutex::Autolock m(mMutex); 552 switch (mActiveRequest) { 553 case NONE: 554 return 0; 555 case PREVIEW: 556 return mPreviewRequestId; 557 case RECORD: 558 return mRecordingRequestId; 559 default: 560 ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest); 561 return 0; 562 } 563} 564 565status_t StreamingProcessor::incrementStreamingIds() { 566 ATRACE_CALL(); 567 Mutex::Autolock m(mMutex); 568 569 mPreviewRequestId++; 570 if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) { 571 mPreviewRequestId = Camera2Client::kPreviewRequestIdStart; 572 } 573 mRecordingRequestId++; 574 if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) { 575 mRecordingRequestId = Camera2Client::kRecordingRequestIdStart; 576 } 577 return OK; 578} 579 580void StreamingProcessor::onFrameAvailable() { 581 ATRACE_CALL(); 582 Mutex::Autolock l(mMutex); 583 if (!mRecordingFrameAvailable) { 584 mRecordingFrameAvailable = true; 585 mRecordingFrameAvailableSignal.signal(); 586 } 587 588} 589 590bool StreamingProcessor::threadLoop() { 591 status_t res; 592 593 { 594 Mutex::Autolock l(mMutex); 595 while (!mRecordingFrameAvailable) { 596 res = mRecordingFrameAvailableSignal.waitRelative( 597 mMutex, kWaitDuration); 598 if (res == TIMED_OUT) return true; 599 } 600 mRecordingFrameAvailable = false; 601 } 602 603 do { 604 res = processRecordingFrame(); 605 } while (res == OK); 606 607 return true; 608} 609 610status_t StreamingProcessor::processRecordingFrame() { 611 ATRACE_CALL(); 612 status_t res; 613 sp<Camera2Heap> recordingHeap; 614 size_t heapIdx = 0; 615 nsecs_t timestamp; 616 617 sp<Camera2Client> client = mClient.promote(); 618 if (client == 0) { 619 // Discard frames during shutdown 620 BufferItemConsumer::BufferItem imgBuffer; 621 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0); 622 if (res != OK) { 623 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 624 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", 625 __FUNCTION__, mId, strerror(-res), res); 626 } 627 return res; 628 } 629 mRecordingConsumer->releaseBuffer(imgBuffer); 630 return OK; 631 } 632 633 { 634 /* acquire SharedParameters before mMutex so we don't dead lock 635 with Camera2Client code calling into StreamingProcessor */ 636 SharedParameters::Lock l(client->getParameters()); 637 Mutex::Autolock m(mMutex); 638 BufferItemConsumer::BufferItem imgBuffer; 639 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0); 640 if (res != OK) { 641 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 642 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", 643 __FUNCTION__, mId, strerror(-res), res); 644 } 645 return res; 646 } 647 timestamp = imgBuffer.mTimestamp; 648 649 mRecordingFrameCount++; 650 ALOGVV("OnRecordingFrame: Frame %d", mRecordingFrameCount); 651 652 if (l.mParameters.state != Parameters::RECORD && 653 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { 654 ALOGV("%s: Camera %d: Discarding recording image buffers " 655 "received after recording done", __FUNCTION__, 656 mId); 657 mRecordingConsumer->releaseBuffer(imgBuffer); 658 return INVALID_OPERATION; 659 } 660 661 if (mRecordingHeap == 0) { 662 const size_t bufferSize = 4 + sizeof(buffer_handle_t); 663 ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of " 664 "size %zu bytes", __FUNCTION__, mId, 665 mRecordingHeapCount, bufferSize); 666 667 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount, 668 "Camera2Client::RecordingHeap"); 669 if (mRecordingHeap->mHeap->getSize() == 0) { 670 ALOGE("%s: Camera %d: Unable to allocate memory for recording", 671 __FUNCTION__, mId); 672 mRecordingConsumer->releaseBuffer(imgBuffer); 673 return NO_MEMORY; 674 } 675 for (size_t i = 0; i < mRecordingBuffers.size(); i++) { 676 if (mRecordingBuffers[i].mBuf != 677 BufferItemConsumer::INVALID_BUFFER_SLOT) { 678 ALOGE("%s: Camera %d: Non-empty recording buffers list!", 679 __FUNCTION__, mId); 680 } 681 } 682 mRecordingBuffers.clear(); 683 mRecordingBuffers.setCapacity(mRecordingHeapCount); 684 mRecordingBuffers.insertAt(0, mRecordingHeapCount); 685 686 mRecordingHeapHead = 0; 687 mRecordingHeapFree = mRecordingHeapCount; 688 } 689 690 if ( mRecordingHeapFree == 0) { 691 ALOGE("%s: Camera %d: No free recording buffers, dropping frame", 692 __FUNCTION__, mId); 693 mRecordingConsumer->releaseBuffer(imgBuffer); 694 return NO_MEMORY; 695 } 696 697 heapIdx = mRecordingHeapHead; 698 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount; 699 mRecordingHeapFree--; 700 701 ALOGVV("%s: Camera %d: Timestamp %lld", 702 __FUNCTION__, mId, timestamp); 703 704 ssize_t offset; 705 size_t size; 706 sp<IMemoryHeap> heap = 707 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset, 708 &size); 709 710 uint8_t *data = (uint8_t*)heap->getBase() + offset; 711 uint32_t type = kMetadataBufferTypeGrallocSource; 712 *((uint32_t*)data) = type; 713 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle; 714 ALOGVV("%s: Camera %d: Sending out buffer_handle_t %p", 715 __FUNCTION__, mId, 716 imgBuffer.mGraphicBuffer->handle); 717 mRecordingBuffers.replaceAt(imgBuffer, heapIdx); 718 recordingHeap = mRecordingHeap; 719 } 720 721 // Call outside locked parameters to allow re-entrancy from notification 722 Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks); 723 if (l.mRemoteCallback != 0) { 724 l.mRemoteCallback->dataCallbackTimestamp(timestamp, 725 CAMERA_MSG_VIDEO_FRAME, 726 recordingHeap->mBuffers[heapIdx]); 727 } else { 728 ALOGW("%s: Camera %d: Remote callback gone", __FUNCTION__, mId); 729 } 730 731 return OK; 732} 733 734void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { 735 ATRACE_CALL(); 736 status_t res; 737 738 Mutex::Autolock m(mMutex); 739 // Make sure this is for the current heap 740 ssize_t offset; 741 size_t size; 742 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 743 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) { 744 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release " 745 "(got %x, expected %x)", __FUNCTION__, mId, 746 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID()); 747 return; 748 } 749 uint8_t *data = (uint8_t*)heap->getBase() + offset; 750 uint32_t type = *(uint32_t*)data; 751 if (type != kMetadataBufferTypeGrallocSource) { 752 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)", 753 __FUNCTION__, mId, type, 754 kMetadataBufferTypeGrallocSource); 755 return; 756 } 757 758 // Release the buffer back to the recording queue 759 760 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4); 761 762 size_t itemIndex; 763 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 764 const BufferItemConsumer::BufferItem item = 765 mRecordingBuffers[itemIndex]; 766 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT && 767 item.mGraphicBuffer->handle == imgHandle) { 768 break; 769 } 770 } 771 if (itemIndex == mRecordingBuffers.size()) { 772 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of " 773 "outstanding buffers", __FUNCTION__, mId, 774 imgHandle); 775 return; 776 } 777 778 ALOGVV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, 779 mId, imgHandle); 780 781 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 782 if (res != OK) { 783 ALOGE("%s: Camera %d: Unable to free recording frame " 784 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 785 mId, imgHandle, strerror(-res), res); 786 return; 787 } 788 mRecordingBuffers.replaceAt(itemIndex); 789 790 mRecordingHeapFree++; 791 ALOGV_IF(mRecordingHeapFree == mRecordingHeapCount, 792 "%s: Camera %d: All %d recording buffers returned", 793 __FUNCTION__, mId, mRecordingHeapCount); 794} 795 796void StreamingProcessor::releaseAllRecordingFramesLocked() { 797 ATRACE_CALL(); 798 status_t res; 799 800 if (mRecordingConsumer == 0) { 801 return; 802 } 803 804 ALOGV("%s: Camera %d: Releasing all recording buffers", __FUNCTION__, 805 mId); 806 807 size_t releasedCount = 0; 808 for (size_t itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 809 const BufferItemConsumer::BufferItem item = 810 mRecordingBuffers[itemIndex]; 811 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) { 812 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 813 if (res != OK) { 814 ALOGE("%s: Camera %d: Unable to free recording frame " 815 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 816 mId, item.mGraphicBuffer->handle, strerror(-res), res); 817 } 818 mRecordingBuffers.replaceAt(itemIndex); 819 releasedCount++; 820 } 821 } 822 823 if (releasedCount > 0) { 824 ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers " 825 "from previous recording session", __FUNCTION__, mId, releasedCount); 826 ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree, 827 "%s: Camera %d: Force-freed %zu buffers, but expected %zu", 828 __FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree); 829 } 830 831 mRecordingHeapHead = 0; 832 mRecordingHeapFree = mRecordingHeapCount; 833} 834 835bool StreamingProcessor::isStreamActive(const Vector<int32_t> &streams, 836 int32_t recordingStreamId) { 837 for (size_t i = 0; i < streams.size(); i++) { 838 if (streams[i] == recordingStreamId) { 839 return true; 840 } 841 } 842 return false; 843} 844 845 846status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) { 847 String8 result; 848 849 result.append(" Current requests:\n"); 850 if (mPreviewRequest.entryCount() != 0) { 851 result.append(" Preview request:\n"); 852 write(fd, result.string(), result.size()); 853 mPreviewRequest.dump(fd, 2, 6); 854 result.clear(); 855 } else { 856 result.append(" Preview request: undefined\n"); 857 } 858 859 if (mRecordingRequest.entryCount() != 0) { 860 result = " Recording request:\n"; 861 write(fd, result.string(), result.size()); 862 mRecordingRequest.dump(fd, 2, 6); 863 result.clear(); 864 } else { 865 result = " Recording request: undefined\n"; 866 } 867 868 const char* streamTypeString[] = { 869 "none", "preview", "record" 870 }; 871 result.append(String8::format(" Active request: %s (paused: %s)\n", 872 streamTypeString[mActiveRequest], 873 mPaused ? "yes" : "no")); 874 875 write(fd, result.string(), result.size()); 876 877 return OK; 878} 879 880}; // namespace camera2 881}; // namespace android 882