StreamingProcessor.cpp revision 73bbd1f1c493835f191ea2b0b72439292496b40a
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 res = device->waitUntilDrained(); 174 if (res != OK) { 175 ALOGE("%s: Error waiting for preview to drain: %s (%d)", 176 __FUNCTION__, strerror(-res), res); 177 return res; 178 } 179 res = device->deleteStream(mPreviewStreamId); 180 if (res != OK) { 181 ALOGE("%s: Unable to delete old preview stream: %s (%d)", 182 __FUNCTION__, strerror(-res), res); 183 return res; 184 } 185 mPreviewStreamId = NO_STREAM; 186 } 187 return OK; 188} 189 190status_t StreamingProcessor::getPreviewStreamId() const { 191 Mutex::Autolock m(mMutex); 192 return mPreviewStreamId; 193} 194 195status_t StreamingProcessor::setRecordingBufferCount(size_t count) { 196 ATRACE_CALL(); 197 // 32 is the current upper limit on the video buffer count for BufferQueue 198 sp<Camera2Client> client = mClient.promote(); 199 if (client == 0) return INVALID_OPERATION; 200 if (count > 32) { 201 ALOGE("%s: Camera %d: Error setting %d as video buffer count value", 202 __FUNCTION__, client->getCameraId(), count); 203 return BAD_VALUE; 204 } 205 206 Mutex::Autolock m(mMutex); 207 208 // Need to reallocate memory for heap 209 if (mRecordingHeapCount != count) { 210 if (mRecordingHeap != 0) { 211 mRecordingHeap.clear(); 212 mRecordingHeap = NULL; 213 } 214 mRecordingHeapCount = count; 215 } 216 217 return OK; 218} 219 220status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { 221 ATRACE_CALL(); 222 status_t res; 223 Mutex::Autolock m(mMutex); 224 225 sp<Camera2Client> client = mClient.promote(); 226 if (client == 0) return INVALID_OPERATION; 227 228 if (mRecordingRequest.entryCount() == 0) { 229 res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD, 230 &mRecordingRequest); 231 if (res != OK) { 232 ALOGE("%s: Camera %d: Unable to create default recording request:" 233 " %s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); 234 return res; 235 } 236 } 237 238 res = params.updateRequest(&mRecordingRequest); 239 if (res != OK) { 240 ALOGE("%s: Camera %d: Unable to update common entries of recording " 241 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 242 strerror(-res), res); 243 return res; 244 } 245 246 return OK; 247} 248 249status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { 250 ATRACE_CALL(); 251 status_t res; 252 Mutex::Autolock m(mMutex); 253 254 sp<Camera2Client> client = mClient.promote(); 255 if (client == 0) return INVALID_OPERATION; 256 sp<Camera2Device> device = client->getCameraDevice(); 257 258 if (mRecordingConsumer == 0) { 259 // Create CPU buffer queue endpoint. We need one more buffer here so that we can 260 // always acquire and free a buffer when the heap is full; otherwise the consumer 261 // will have buffers in flight we'll never clear out. 262 mRecordingConsumer = new BufferItemConsumer( 263 GRALLOC_USAGE_HW_VIDEO_ENCODER, 264 mRecordingHeapCount + 1, 265 true); 266 mRecordingConsumer->setFrameAvailableListener(this); 267 mRecordingConsumer->setName(String8("Camera2-RecordingConsumer")); 268 mRecordingWindow = new SurfaceTextureClient( 269 mRecordingConsumer->getProducerInterface()); 270 // Allocate memory later, since we don't know buffer size until receipt 271 } 272 273 if (mRecordingStreamId != NO_STREAM) { 274 // Check if stream parameters have to change 275 uint32_t currentWidth, currentHeight; 276 res = device->getStreamInfo(mRecordingStreamId, 277 ¤tWidth, ¤tHeight, 0); 278 if (res != OK) { 279 ALOGE("%s: Camera %d: Error querying recording output stream info: " 280 "%s (%d)", __FUNCTION__, client->getCameraId(), 281 strerror(-res), res); 282 return res; 283 } 284 if (currentWidth != (uint32_t)params.videoWidth || 285 currentHeight != (uint32_t)params.videoHeight) { 286 // TODO: Should wait to be sure previous recording has finished 287 res = device->deleteStream(mRecordingStreamId); 288 if (res != OK) { 289 ALOGE("%s: Camera %d: Unable to delete old output stream " 290 "for recording: %s (%d)", __FUNCTION__, 291 client->getCameraId(), strerror(-res), res); 292 return res; 293 } 294 mRecordingStreamId = NO_STREAM; 295 } 296 } 297 298 if (mRecordingStreamId == NO_STREAM) { 299 mRecordingFrameCount = 0; 300 res = device->createStream(mRecordingWindow, 301 params.videoWidth, params.videoHeight, 302 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId); 303 if (res != OK) { 304 ALOGE("%s: Camera %d: Can't create output stream for recording: " 305 "%s (%d)", __FUNCTION__, client->getCameraId(), 306 strerror(-res), res); 307 return res; 308 } 309 } 310 311 return OK; 312} 313 314status_t StreamingProcessor::deleteRecordingStream() { 315 ATRACE_CALL(); 316 status_t res; 317 318 Mutex::Autolock m(mMutex); 319 320 if (mRecordingStreamId != NO_STREAM) { 321 sp<Camera2Client> client = mClient.promote(); 322 if (client == 0) return INVALID_OPERATION; 323 sp<Camera2Device> device = client->getCameraDevice(); 324 325 res = device->waitUntilDrained(); 326 if (res != OK) { 327 ALOGE("%s: Error waiting for HAL to drain: %s (%d)", 328 __FUNCTION__, strerror(-res), res); 329 return res; 330 } 331 res = device->deleteStream(mRecordingStreamId); 332 if (res != OK) { 333 ALOGE("%s: Unable to delete recording stream: %s (%d)", 334 __FUNCTION__, strerror(-res), res); 335 return res; 336 } 337 mRecordingStreamId = NO_STREAM; 338 } 339 return OK; 340} 341 342status_t StreamingProcessor::getRecordingStreamId() const { 343 return mRecordingStreamId; 344} 345 346status_t StreamingProcessor::startStream(StreamType type, 347 const Vector<uint8_t> &outputStreams) { 348 ATRACE_CALL(); 349 status_t res; 350 351 sp<Camera2Client> client = mClient.promote(); 352 if (client == 0) return INVALID_OPERATION; 353 354 Mutex::Autolock m(mMutex); 355 356 CameraMetadata &request = (type == PREVIEW) ? 357 mPreviewRequest : mRecordingRequest; 358 359 res = request.update( 360 ANDROID_REQUEST_OUTPUT_STREAMS, 361 outputStreams); 362 if (res != OK) { 363 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)", 364 __FUNCTION__, client->getCameraId(), strerror(-res), res); 365 return res; 366 } 367 368 res = request.sort(); 369 if (res != OK) { 370 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)", 371 __FUNCTION__, client->getCameraId(), strerror(-res), res); 372 return res; 373 } 374 375 res = client->getCameraDevice()->setStreamingRequest(request); 376 if (res != OK) { 377 ALOGE("%s: Camera %d: Unable to set preview request to start preview: " 378 "%s (%d)", 379 __FUNCTION__, client->getCameraId(), strerror(-res), res); 380 return res; 381 } 382 383 return OK; 384} 385 386status_t StreamingProcessor::stopStream() { 387 ATRACE_CALL(); 388 status_t res; 389 390 sp<Camera2Client> client = mClient.promote(); 391 if (client == 0) return INVALID_OPERATION; 392 sp<Camera2Device> device = client->getCameraDevice(); 393 394 res = device->clearStreamingRequest(); 395 if (res != OK) { 396 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", 397 __FUNCTION__, client->getCameraId(), strerror(-res), res); 398 return res; 399 } 400 res = device->waitUntilDrained(); 401 if (res != OK) { 402 ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", 403 __FUNCTION__, client->getCameraId(), strerror(-res), res); 404 return res; 405 } 406 return OK; 407} 408 409void StreamingProcessor::onFrameAvailable() { 410 ATRACE_CALL(); 411 status_t res; 412 sp<Camera2Heap> recordingHeap; 413 size_t heapIdx = 0; 414 nsecs_t timestamp; 415 416 sp<Camera2Client> client = mClient.promote(); 417 if (client == 0) return; 418 419 { 420 Mutex::Autolock m(mMutex); 421 BufferItemConsumer::BufferItem imgBuffer; 422 res = mRecordingConsumer->acquireBuffer(&imgBuffer); 423 if (res != OK) { 424 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", 425 __FUNCTION__, client->getCameraId(), strerror(-res), res); 426 return; 427 } 428 timestamp = imgBuffer.mTimestamp; 429 430 mRecordingFrameCount++; 431 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount); 432 433 { 434 SharedParameters::Lock l(client->getParameters()); 435 // TODO: Signal errors here upstream 436 if (l.mParameters.state != Parameters::RECORD && 437 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { 438 ALOGV("%s: Camera %d: Discarding recording image buffers " 439 "received after recording done", __FUNCTION__, 440 client->getCameraId()); 441 mRecordingConsumer->releaseBuffer(imgBuffer); 442 return; 443 } 444 } 445 446 if (mRecordingHeap == 0) { 447 const size_t bufferSize = 4 + sizeof(buffer_handle_t); 448 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of " 449 "size %d bytes", __FUNCTION__, client->getCameraId(), 450 mRecordingHeapCount, bufferSize); 451 452 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount, 453 "Camera2Client::RecordingHeap"); 454 if (mRecordingHeap->mHeap->getSize() == 0) { 455 ALOGE("%s: Camera %d: Unable to allocate memory for recording", 456 __FUNCTION__, client->getCameraId()); 457 mRecordingConsumer->releaseBuffer(imgBuffer); 458 return; 459 } 460 for (size_t i = 0; i < mRecordingBuffers.size(); i++) { 461 if (mRecordingBuffers[i].mBuf != 462 BufferItemConsumer::INVALID_BUFFER_SLOT) { 463 ALOGE("%s: Camera %d: Non-empty recording buffers list!", 464 __FUNCTION__, client->getCameraId()); 465 } 466 } 467 mRecordingBuffers.clear(); 468 mRecordingBuffers.setCapacity(mRecordingHeapCount); 469 mRecordingBuffers.insertAt(0, mRecordingHeapCount); 470 471 mRecordingHeapHead = 0; 472 mRecordingHeapFree = mRecordingHeapCount; 473 } 474 475 if ( mRecordingHeapFree == 0) { 476 ALOGE("%s: Camera %d: No free recording buffers, dropping frame", 477 __FUNCTION__, client->getCameraId()); 478 mRecordingConsumer->releaseBuffer(imgBuffer); 479 return; 480 } 481 482 heapIdx = mRecordingHeapHead; 483 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount; 484 mRecordingHeapFree--; 485 486 ALOGV("%s: Camera %d: Timestamp %lld", 487 __FUNCTION__, client->getCameraId(), timestamp); 488 489 ssize_t offset; 490 size_t size; 491 sp<IMemoryHeap> heap = 492 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset, 493 &size); 494 495 uint8_t *data = (uint8_t*)heap->getBase() + offset; 496 uint32_t type = kMetadataBufferTypeGrallocSource; 497 *((uint32_t*)data) = type; 498 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle; 499 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p", 500 __FUNCTION__, client->getCameraId(), 501 imgBuffer.mGraphicBuffer->handle); 502 mRecordingBuffers.replaceAt(imgBuffer, heapIdx); 503 recordingHeap = mRecordingHeap; 504 } 505 506 // Call outside locked parameters to allow re-entrancy from notification 507 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient); 508 if (l.mCameraClient != 0) { 509 l.mCameraClient->dataCallbackTimestamp(timestamp, 510 CAMERA_MSG_VIDEO_FRAME, 511 recordingHeap->mBuffers[heapIdx]); 512 } 513} 514 515void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { 516 ATRACE_CALL(); 517 status_t res; 518 519 sp<Camera2Client> client = mClient.promote(); 520 if (client == 0) return; 521 522 Mutex::Autolock m(mMutex); 523 // Make sure this is for the current heap 524 ssize_t offset; 525 size_t size; 526 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 527 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) { 528 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release " 529 "(got %x, expected %x)", __FUNCTION__, client->getCameraId(), 530 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID()); 531 return; 532 } 533 uint8_t *data = (uint8_t*)heap->getBase() + offset; 534 uint32_t type = *(uint32_t*)data; 535 if (type != kMetadataBufferTypeGrallocSource) { 536 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)", 537 __FUNCTION__, client->getCameraId(), type, 538 kMetadataBufferTypeGrallocSource); 539 return; 540 } 541 542 // Release the buffer back to the recording queue 543 544 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4); 545 546 size_t itemIndex; 547 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { 548 const BufferItemConsumer::BufferItem item = 549 mRecordingBuffers[itemIndex]; 550 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT && 551 item.mGraphicBuffer->handle == imgHandle) { 552 break; 553 } 554 } 555 if (itemIndex == mRecordingBuffers.size()) { 556 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of " 557 "outstanding buffers", __FUNCTION__, client->getCameraId(), 558 imgHandle); 559 return; 560 } 561 562 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, 563 client->getCameraId(), imgHandle); 564 565 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); 566 if (res != OK) { 567 ALOGE("%s: Camera %d: Unable to free recording frame " 568 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, 569 client->getCameraId(), imgHandle, strerror(-res), res); 570 return; 571 } 572 mRecordingBuffers.replaceAt(itemIndex); 573 574 mRecordingHeapFree++; 575} 576 577 578status_t StreamingProcessor::dump(int fd, const Vector<String16>& args) { 579 String8 result; 580 581 result.append(" Current requests:\n"); 582 if (mPreviewRequest.entryCount() != 0) { 583 result.append(" Preview request:\n"); 584 write(fd, result.string(), result.size()); 585 mPreviewRequest.dump(fd, 2, 6); 586 } else { 587 result.append(" Preview request: undefined\n"); 588 write(fd, result.string(), result.size()); 589 } 590 591 if (mRecordingRequest.entryCount() != 0) { 592 result = " Recording request:\n"; 593 write(fd, result.string(), result.size()); 594 mRecordingRequest.dump(fd, 2, 6); 595 } else { 596 result = " Recording request: undefined\n"; 597 write(fd, result.string(), result.size()); 598 } 599 600 return OK; 601} 602 603}; // namespace camera2 604}; // namespace android 605