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