StreamingProcessor.cpp revision 04273cb14d2326e85bb047ea6ef75294c8b3d561
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 21#include <utils/Log.h> 22#include <utils/Trace.h> 23#include <gui/SurfaceTextureClient.h> 24#include <media/hardware/MetadataBufferType.h> 25 26#include "StreamingProcessor.h" 27#include "Camera2Heap.h" 28#include "../Camera2Client.h" 29#include "../Camera2Device.h" 30 31namespace android { 32namespace camera2 { 33 34StreamingProcessor::StreamingProcessor(wp<Camera2Client> client): 35 mClient(client), 36 mPreviewStreamId(NO_STREAM), 37 mRecordingStreamId(NO_STREAM), 38 mRecordingHeapCount(kDefaultRecordingHeapCount) 39{ 40 41} 42 43StreamingProcessor::~StreamingProcessor() { 44 deletePreviewStream(); 45 deleteRecordingStream(); 46} 47 48status_t StreamingProcessor::setPreviewWindow(sp<ANativeWindow> window) { 49 ATRACE_CALL(); 50 status_t res; 51 52 res = deletePreviewStream(); 53 if (res != OK) return res; 54 55 Mutex::Autolock m(mMutex); 56 57 mPreviewWindow = window; 58 59 return OK; 60} 61 62bool StreamingProcessor::haveValidPreviewWindow() const { 63 Mutex::Autolock m(mMutex); 64 return mPreviewWindow != 0; 65} 66 67status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { 68 ATRACE_CALL(); 69 status_t res; 70 sp<Camera2Client> client = mClient.promote(); 71 if (client == 0) return INVALID_OPERATION; 72 73 Mutex::Autolock m(mMutex); 74 if (mPreviewRequest.entryCount() == 0) { 75 res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 76 &mPreviewRequest); 77 if (res != OK) { 78 ALOGE("%s: Camera %d: Unable to create default preview request: " 79 "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 80 return res; 81 } 82 } 83 84 res = params.updateRequest(&mPreviewRequest); 85 if (res != OK) { 86 ALOGE("%s: Camera %d: Unable to update common entries of preview " 87 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 88 strerror(-res), res); 89 return res; 90 } 91 92 res = mPreviewRequest.update(ANDROID_REQUEST_ID, 93 &Camera2Client::kPreviewRequestId, 1); 94 95 return OK; 96} 97 98status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { 99 ATRACE_CALL(); 100 Mutex::Autolock m(mMutex); 101 102 status_t res; 103 sp<Camera2Client> client = mClient.promote(); 104 if (client == 0) return INVALID_OPERATION; 105 sp<Camera2Device> device = client->getCameraDevice(); 106 107 if (mPreviewStreamId != NO_STREAM) { 108 // Check if stream parameters have to change 109 uint32_t currentWidth, currentHeight; 110 res = device->getStreamInfo(mPreviewStreamId, 111 ¤tWidth, ¤tHeight, 0); 112 if (res != OK) { 113 ALOGE("%s: Camera %d: Error querying preview stream info: " 114 "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 115 return res; 116 } 117 if (currentWidth != (uint32_t)params.previewWidth || 118 currentHeight != (uint32_t)params.previewHeight) { 119 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d", 120 __FUNCTION__, client->getCameraId(), currentWidth, currentHeight, 121 params.previewWidth, params.previewHeight); 122 res = device->waitUntilDrained(); 123 if (res != OK) { 124 ALOGE("%s: Camera %d: Error waiting for preview to drain: " 125 "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 126 return res; 127 } 128 res = device->deleteStream(mPreviewStreamId); 129 if (res != OK) { 130 ALOGE("%s: Camera %d: Unable to delete old output stream " 131 "for preview: %s (%d)", __FUNCTION__, client->getCameraId(), 132 strerror(-res), res); 133 return res; 134 } 135 mPreviewStreamId = NO_STREAM; 136 } 137 } 138 139 if (mPreviewStreamId == NO_STREAM) { 140 res = device->createStream(mPreviewWindow, 141 params.previewWidth, params.previewHeight, 142 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, 143 &mPreviewStreamId); 144 if (res != OK) { 145 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)", 146 __FUNCTION__, client->getCameraId(), strerror(-res), res); 147 return res; 148 } 149 } 150 151 res = device->setStreamTransform(mPreviewStreamId, 152 params.previewTransform); 153 if (res != OK) { 154 ALOGE("%s: Camera %d: Unable to set preview stream transform: " 155 "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 156 return res; 157 } 158 159 return OK; 160} 161 162status_t StreamingProcessor::deletePreviewStream() { 163 ATRACE_CALL(); 164 status_t res; 165 166 Mutex::Autolock m(mMutex); 167 168 if (mPreviewStreamId != NO_STREAM) { 169 sp<Camera2Client> client = mClient.promote(); 170 if (client == 0) return INVALID_OPERATION; 171 sp<Camera2Device> device = client->getCameraDevice(); 172 173 ALOGV("%s: for cameraId %d on streamId %d", 174 __FUNCTION__, client->getCameraId(), mPreviewStreamId); 175 176 res = device->waitUntilDrained(); 177 if (res != OK) { 178 ALOGE("%s: Error waiting for preview to drain: %s (%d)", 179 __FUNCTION__, strerror(-res), res); 180 return res; 181 } 182 res = device->deleteStream(mPreviewStreamId); 183 if (res != OK) { 184 ALOGE("%s: Unable to delete old preview stream: %s (%d)", 185 __FUNCTION__, strerror(-res), res); 186 return res; 187 } 188 mPreviewStreamId = NO_STREAM; 189 } 190 return OK; 191} 192 193status_t StreamingProcessor::getPreviewStreamId() const { 194 Mutex::Autolock m(mMutex); 195 return mPreviewStreamId; 196} 197 198status_t StreamingProcessor::setRecordingBufferCount(size_t count) { 199 ATRACE_CALL(); 200 // 32 is the current upper limit on the video buffer count for BufferQueue 201 sp<Camera2Client> client = mClient.promote(); 202 if (client == 0) return INVALID_OPERATION; 203 if (count > 32) { 204 ALOGE("%s: Camera %d: Error setting %d as video buffer count value", 205 __FUNCTION__, client->getCameraId(), count); 206 return BAD_VALUE; 207 } 208 209 Mutex::Autolock m(mMutex); 210 211 // Need to reallocate memory for heap 212 if (mRecordingHeapCount != count) { 213 if (mRecordingHeap != 0) { 214 mRecordingHeap.clear(); 215 mRecordingHeap = NULL; 216 } 217 mRecordingHeapCount = count; 218 } 219 220 return OK; 221} 222 223status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { 224 ATRACE_CALL(); 225 status_t res; 226 Mutex::Autolock m(mMutex); 227 228 sp<Camera2Client> client = mClient.promote(); 229 if (client == 0) return INVALID_OPERATION; 230 231 if (mRecordingRequest.entryCount() == 0) { 232 res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD, 233 &mRecordingRequest); 234 if (res != OK) { 235 ALOGE("%s: Camera %d: Unable to create default recording request:" 236 " %s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 237 return res; 238 } 239 } 240 241 res = params.updateRequest(&mRecordingRequest); 242 if (res != OK) { 243 ALOGE("%s: Camera %d: Unable to update common entries of recording " 244 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 245 strerror(-res), res); 246 return res; 247 } 248 249 return OK; 250} 251 252status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { 253 ATRACE_CALL(); 254 status_t res; 255 Mutex::Autolock m(mMutex); 256 257 sp<Camera2Client> client = mClient.promote(); 258 if (client == 0) return INVALID_OPERATION; 259 sp<Camera2Device> device = client->getCameraDevice(); 260 261 if (mRecordingConsumer == 0) { 262 // Create CPU buffer queue endpoint. We need one more buffer here so that we can 263 // always acquire and free a buffer when the heap is full; otherwise the consumer 264 // will have buffers in flight we'll never clear out. 265 mRecordingConsumer = new BufferItemConsumer( 266 GRALLOC_USAGE_HW_VIDEO_ENCODER, 267 mRecordingHeapCount + 1, 268 true); 269 mRecordingConsumer->setFrameAvailableListener(this); 270 mRecordingConsumer->setName(String8("Camera2-RecordingConsumer")); 271 mRecordingWindow = new SurfaceTextureClient( 272 mRecordingConsumer->getProducerInterface()); 273 // Allocate memory later, since we don't know buffer size until receipt 274 } 275 276 if (mRecordingStreamId != NO_STREAM) { 277 // Check if stream parameters have to change 278 uint32_t currentWidth, currentHeight; 279 res = device->getStreamInfo(mRecordingStreamId, 280 ¤tWidth, ¤tHeight, 0); 281 if (res != OK) { 282 ALOGE("%s: Camera %d: Error querying recording output stream info: " 283 "%s (%d)", __FUNCTION__, client->getCameraId(), 284 strerror(-res), res); 285 return res; 286 } 287 if (currentWidth != (uint32_t)params.videoWidth || 288 currentHeight != (uint32_t)params.videoHeight) { 289 // TODO: Should wait to be sure previous recording has finished 290 res = device->deleteStream(mRecordingStreamId); 291 if (res != OK) { 292 ALOGE("%s: Camera %d: Unable to delete old output stream " 293 "for recording: %s (%d)", __FUNCTION__, 294 client->getCameraId(), strerror(-res), res); 295 return res; 296 } 297 mRecordingStreamId = NO_STREAM; 298 } 299 } 300 301 if (mRecordingStreamId == NO_STREAM) { 302 mRecordingFrameCount = 0; 303 res = device->createStream(mRecordingWindow, 304 params.videoWidth, params.videoHeight, 305 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId); 306 if (res != OK) { 307 ALOGE("%s: Camera %d: Can't create output stream for recording: " 308 "%s (%d)", __FUNCTION__, client->getCameraId(), 309 strerror(-res), res); 310 return res; 311 } 312 } 313 314 return OK; 315} 316 317status_t StreamingProcessor::deleteRecordingStream() { 318 ATRACE_CALL(); 319 status_t res; 320 321 Mutex::Autolock m(mMutex); 322 323 if (mRecordingStreamId != NO_STREAM) { 324 sp<Camera2Client> client = mClient.promote(); 325 if (client == 0) return INVALID_OPERATION; 326 sp<Camera2Device> device = client->getCameraDevice(); 327 328 res = device->waitUntilDrained(); 329 if (res != OK) { 330 ALOGE("%s: Error waiting for HAL to drain: %s (%d)", 331 __FUNCTION__, strerror(-res), res); 332 return res; 333 } 334 res = device->deleteStream(mRecordingStreamId); 335 if (res != OK) { 336 ALOGE("%s: Unable to delete recording stream: %s (%d)", 337 __FUNCTION__, strerror(-res), res); 338 return res; 339 } 340 mRecordingStreamId = NO_STREAM; 341 } 342 return OK; 343} 344 345status_t StreamingProcessor::getRecordingStreamId() const { 346 return mRecordingStreamId; 347} 348 349status_t StreamingProcessor::startStream(StreamType type, 350 const Vector<uint8_t> &outputStreams) { 351 ATRACE_CALL(); 352 status_t res; 353 354 sp<Camera2Client> client = mClient.promote(); 355 if (client == 0) return INVALID_OPERATION; 356 357 ALOGV("%s: Camera %d: type = %d", __FUNCTION__, client->getCameraId(), type); 358 359 Mutex::Autolock m(mMutex); 360 361 CameraMetadata &request = (type == PREVIEW) ? 362 mPreviewRequest : mRecordingRequest; 363 364 res = request.update( 365 ANDROID_REQUEST_OUTPUT_STREAMS, 366 outputStreams); 367 if (res != OK) { 368 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)", 369 __FUNCTION__, client->getCameraId(), strerror(-res), res); 370 return res; 371 } 372 373 res = request.sort(); 374 if (res != OK) { 375 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)", 376 __FUNCTION__, client->getCameraId(), strerror(-res), res); 377 return res; 378 } 379 380 res = client->getCameraDevice()->setStreamingRequest(request); 381 if (res != OK) { 382 ALOGE("%s: Camera %d: Unable to set preview request to start preview: " 383 "%s (%d)", 384 __FUNCTION__, client->getCameraId(), strerror(-res), res); 385 return res; 386 } 387 388 return OK; 389} 390 391status_t StreamingProcessor::stopStream() { 392 ATRACE_CALL(); 393 status_t res; 394 395 sp<Camera2Client> client = mClient.promote(); 396 if (client == 0) return INVALID_OPERATION; 397 sp<Camera2Device> device = client->getCameraDevice(); 398 399 res = device->clearStreamingRequest(); 400 if (res != OK) { 401 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 402 __FUNCTION__, client->getCameraId(), strerror(-res), res); 403 return res; 404 } 405 res = device->waitUntilDrained(); 406 if (res != OK) { 407 ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", 408 __FUNCTION__, client->getCameraId(), strerror(-res), res); 409 return res; 410 } 411 return OK; 412} 413 414void StreamingProcessor::onFrameAvailable() { 415 ATRACE_CALL(); 416 status_t res; 417 sp<Camera2Heap> recordingHeap; 418 size_t heapIdx = 0; 419 nsecs_t timestamp; 420 421 sp<Camera2Client> client = mClient.promote(); 422 if (client == 0) return; 423 424 { 425 /* acquire SharedParameters before mMutex so we don't dead lock 426 with Camera2Client code calling into StreamingProcessor */ 427 SharedParameters::Lock l(client->getParameters()); 428 Mutex::Autolock m(mMutex); 429 BufferItemConsumer::BufferItem imgBuffer; 430 res = mRecordingConsumer->acquireBuffer(&imgBuffer); 431 if (res != OK) { 432 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", 433 __FUNCTION__, client->getCameraId(), strerror(-res), res); 434 return; 435 } 436 timestamp = imgBuffer.mTimestamp; 437 438 mRecordingFrameCount++; 439 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount); 440 441 // TODO: Signal errors here upstream 442 if (l.mParameters.state != Parameters::RECORD && 443 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { 444 ALOGV("%s: Camera %d: Discarding recording image buffers " 445 "received after recording done", __FUNCTION__, 446 client->getCameraId()); 447 mRecordingConsumer->releaseBuffer(imgBuffer); 448 return; 449 } 450 451 if (mRecordingHeap == 0) { 452 const size_t bufferSize = 4 + sizeof(buffer_handle_t); 453 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of " 454 "size %d bytes", __FUNCTION__, client->getCameraId(), 455 mRecordingHeapCount, bufferSize); 456 457 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount, 458 "Camera2Client::RecordingHeap"); 459 if (mRecordingHeap->mHeap->getSize() == 0) { 460 ALOGE("%s: Camera %d: Unable to allocate memory for recording", 461 __FUNCTION__, client->getCameraId()); 462 mRecordingConsumer->releaseBuffer(imgBuffer); 463 return; 464 } 465 for (size_t i = 0; i < mRecordingBuffers.size(); i++) { 466 if (mRecordingBuffers[i].mBuf != 467 BufferItemConsumer::INVALID_BUFFER_SLOT) { 468 ALOGE("%s: Camera %d: Non-empty recording buffers list!", 469 __FUNCTION__, client->getCameraId()); 470 } 471 } 472 mRecordingBuffers.clear(); 473 mRecordingBuffers.setCapacity(mRecordingHeapCount); 474 mRecordingBuffers.insertAt(0, mRecordingHeapCount); 475 476 mRecordingHeapHead = 0; 477 mRecordingHeapFree = mRecordingHeapCount; 478 } 479 480 if ( mRecordingHeapFree == 0) { 481 ALOGE("%s: Camera %d: No free recording buffers, dropping frame", 482 __FUNCTION__, client->getCameraId()); 483 mRecordingConsumer->releaseBuffer(imgBuffer); 484 return; 485 } 486 487 heapIdx = mRecordingHeapHead; 488 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount; 489 mRecordingHeapFree--; 490 491 ALOGV("%s: Camera %d: Timestamp %lld", 492 __FUNCTION__, client->getCameraId(), timestamp); 493 494 ssize_t offset; 495 size_t size; 496 sp<IMemoryHeap> heap = 497 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset, 498 &size); 499 500 uint8_t *data = (uint8_t*)heap->getBase() + offset; 501 uint32_t type = kMetadataBufferTypeGrallocSource; 502 *((uint32_t*)data) = type; 503 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle; 504 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p", 505 __FUNCTION__, client->getCameraId(), 506 imgBuffer.mGraphicBuffer->handle); 507 mRecordingBuffers.replaceAt(imgBuffer, heapIdx); 508 recordingHeap = mRecordingHeap; 509 } 510 511 // Call outside locked parameters to allow re-entrancy from notification 512 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient); 513 if (l.mCameraClient != 0) { 514 l.mCameraClient->dataCallbackTimestamp(timestamp, 515 CAMERA_MSG_VIDEO_FRAME, 516 recordingHeap->mBuffers[heapIdx]); 517 } 518} 519 520void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { 521 ATRACE_CALL(); 522 status_t res; 523 524 sp<Camera2Client> client = mClient.promote(); 525 if (client == 0) return; 526 527 Mutex::Autolock m(mMutex); 528 // Make sure this is for the current heap 529 ssize_t offset; 530 size_t size; 531 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 532 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) { 533 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release " 534 "(got %x, expected %x)", __FUNCTION__, client->getCameraId(), 535 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID()); 536 return; 537 } 538 uint8_t *data = (uint8_t*)heap->getBase() + offset; 539 uint32_t type = *(uint32_t*)data; 540 if (type != kMetadataBufferTypeGrallocSource) { 541 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)", 542 __FUNCTION__, client->getCameraId(), type, 543 kMetadataBufferTypeGrallocSource); 544 return; 545 } 546 547 // Release the buffer back to the recording queue 548 549 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4); 550 551 size_t itemIndex; 552 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 553 const BufferItemConsumer::BufferItem item = 554 mRecordingBuffers[itemIndex]; 555 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT && 556 item.mGraphicBuffer->handle == imgHandle) { 557 break; 558 } 559 } 560 if (itemIndex == mRecordingBuffers.size()) { 561 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of " 562 "outstanding buffers", __FUNCTION__, client->getCameraId(), 563 imgHandle); 564 return; 565 } 566 567 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, 568 client->getCameraId(), imgHandle); 569 570 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 571 if (res != OK) { 572 ALOGE("%s: Camera %d: Unable to free recording frame " 573 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 574 client->getCameraId(), imgHandle, strerror(-res), res); 575 return; 576 } 577 mRecordingBuffers.replaceAt(itemIndex); 578 579 mRecordingHeapFree++; 580} 581 582 583status_t StreamingProcessor::dump(int fd, const Vector<String16>& args) { 584 String8 result; 585 586 result.append(" Current requests:\n"); 587 if (mPreviewRequest.entryCount() != 0) { 588 result.append(" Preview request:\n"); 589 write(fd, result.string(), result.size()); 590 mPreviewRequest.dump(fd, 2, 6); 591 } else { 592 result.append(" Preview request: undefined\n"); 593 write(fd, result.string(), result.size()); 594 } 595 596 if (mRecordingRequest.entryCount() != 0) { 597 result = " Recording request:\n"; 598 write(fd, result.string(), result.size()); 599 mRecordingRequest.dump(fd, 2, 6); 600 } else { 601 result = " Recording request: undefined\n"; 602 write(fd, result.string(), result.size()); 603 } 604 605 return OK; 606} 607 608}; // namespace camera2 609}; // namespace android 610