ZslProcessor.cpp revision 97b38a81ac989ccba02d726011a82541f14166df
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 "Camera2Client::ZslProcessor" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20//#define LOG_NNDEBUG 0 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 31#include "ZslProcessor.h" 32#include <gui/SurfaceTextureClient.h> 33#include "../Camera2Device.h" 34#include "../Camera2Client.h" 35 36 37namespace android { 38namespace camera2 { 39 40ZslProcessor::ZslProcessor( 41 wp<Camera2Client> client, 42 wp<CaptureSequencer> sequencer): 43 Thread(false), 44 mState(RUNNING), 45 mClient(client), 46 mSequencer(sequencer), 47 mZslBufferAvailable(false), 48 mZslStreamId(NO_STREAM), 49 mZslReprocessStreamId(NO_STREAM), 50 mFrameListHead(0), 51 mZslQueueHead(0), 52 mZslQueueTail(0) { 53 mZslQueue.insertAt(0, kZslBufferDepth); 54 mFrameList.insertAt(0, kFrameListDepth); 55 sp<CaptureSequencer> captureSequencer = mSequencer.promote(); 56 if (captureSequencer != 0) captureSequencer->setZslProcessor(this); 57} 58 59ZslProcessor::~ZslProcessor() { 60 ALOGV("%s: Exit", __FUNCTION__); 61 deleteStream(); 62} 63 64void ZslProcessor::onFrameAvailable() { 65 Mutex::Autolock l(mInputMutex); 66 if (!mZslBufferAvailable) { 67 mZslBufferAvailable = true; 68 mZslBufferAvailableSignal.signal(); 69 } 70} 71 72void ZslProcessor::onFrameAvailable(int32_t frameId, CameraMetadata &frame) { 73 Mutex::Autolock l(mInputMutex); 74 camera_metadata_entry_t entry; 75 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 76 nsecs_t timestamp = entry.data.i64[0]; 77 ALOGVV("Got preview frame for timestamp %lld", timestamp); 78 79 if (mState != RUNNING) return; 80 81 mFrameList.editItemAt(mFrameListHead).acquire(frame); 82 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; 83 84 findMatchesLocked(); 85} 86 87void ZslProcessor::onBufferReleased(buffer_handle_t *handle) { 88 Mutex::Autolock l(mInputMutex); 89 90 // Verify that the buffer is in our queue 91 size_t i = 0; 92 for (; i < mZslQueue.size(); i++) { 93 if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break; 94 } 95 if (i == mZslQueue.size()) { 96 ALOGW("%s: Released buffer %p not found in queue", 97 __FUNCTION__, handle); 98 } 99 100 mState = RUNNING; 101} 102 103status_t ZslProcessor::updateStream(const Parameters ¶ms) { 104 ATRACE_CALL(); 105 ALOGV("%s: Configuring ZSL streams", __FUNCTION__); 106 status_t res; 107 108 Mutex::Autolock l(mInputMutex); 109 110 sp<Camera2Client> client = mClient.promote(); 111 if (client == 0) return OK; 112 sp<Camera2Device> device = client->getCameraDevice(); 113 114 if (mZslConsumer == 0) { 115 // Create CPU buffer queue endpoint 116 mZslConsumer = new BufferItemConsumer( 117 GRALLOC_USAGE_HW_CAMERA_ZSL, 118 kZslBufferDepth, 119 true); 120 mZslConsumer->setFrameAvailableListener(this); 121 mZslConsumer->setName(String8("Camera2Client::ZslConsumer")); 122 mZslWindow = new SurfaceTextureClient( 123 mZslConsumer->getProducerInterface()); 124 } 125 126 if (mZslStreamId != NO_STREAM) { 127 // Check if stream parameters have to change 128 uint32_t currentWidth, currentHeight; 129 res = device->getStreamInfo(mZslStreamId, 130 ¤tWidth, ¤tHeight, 0); 131 if (res != OK) { 132 ALOGE("%s: Camera %d: Error querying capture output stream info: " 133 "%s (%d)", __FUNCTION__, 134 client->getCameraId(), strerror(-res), res); 135 return res; 136 } 137 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || 138 currentHeight != (uint32_t)params.fastInfo.arrayHeight) { 139 res = device->deleteReprocessStream(mZslReprocessStreamId); 140 if (res != OK) { 141 ALOGE("%s: Camera %d: Unable to delete old reprocess stream " 142 "for ZSL: %s (%d)", __FUNCTION__, 143 client->getCameraId(), strerror(-res), res); 144 return res; 145 } 146 res = device->deleteStream(mZslStreamId); 147 if (res != OK) { 148 ALOGE("%s: Camera %d: Unable to delete old output stream " 149 "for ZSL: %s (%d)", __FUNCTION__, 150 client->getCameraId(), strerror(-res), res); 151 return res; 152 } 153 mZslStreamId = NO_STREAM; 154 } 155 } 156 157 if (mZslStreamId == NO_STREAM) { 158 // Create stream for HAL production 159 // TODO: Sort out better way to select resolution for ZSL 160 res = device->createStream(mZslWindow, 161 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, 162 CAMERA2_HAL_PIXEL_FORMAT_ZSL, 0, 163 &mZslStreamId); 164 if (res != OK) { 165 ALOGE("%s: Camera %d: Can't create output stream for ZSL: " 166 "%s (%d)", __FUNCTION__, client->getCameraId(), 167 strerror(-res), res); 168 return res; 169 } 170 res = device->createReprocessStreamFromStream(mZslStreamId, 171 &mZslReprocessStreamId); 172 if (res != OK) { 173 ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: " 174 "%s (%d)", __FUNCTION__, client->getCameraId(), 175 strerror(-res), res); 176 return res; 177 } 178 } 179 client->registerFrameListener(Camera2Client::kPreviewRequestId, this); 180 181 return OK; 182} 183 184status_t ZslProcessor::deleteStream() { 185 ATRACE_CALL(); 186 status_t res; 187 188 Mutex::Autolock l(mInputMutex); 189 190 if (mZslStreamId != NO_STREAM) { 191 sp<Camera2Client> client = mClient.promote(); 192 if (client == 0) return OK; 193 sp<Camera2Device> device = client->getCameraDevice(); 194 195 res = device->deleteReprocessStream(mZslReprocessStreamId); 196 if (res != OK) { 197 ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: " 198 "%s (%d)", __FUNCTION__, client->getCameraId(), 199 mZslReprocessStreamId, strerror(-res), res); 200 return res; 201 } 202 203 mZslReprocessStreamId = NO_STREAM; 204 res = device->deleteStream(mZslStreamId); 205 if (res != OK) { 206 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: " 207 "%s (%d)", __FUNCTION__, client->getCameraId(), 208 mZslStreamId, strerror(-res), res); 209 return res; 210 } 211 212 mZslWindow.clear(); 213 mZslConsumer.clear(); 214 215 mZslStreamId = NO_STREAM; 216 } 217 return OK; 218} 219 220int ZslProcessor::getStreamId() const { 221 Mutex::Autolock l(mInputMutex); 222 return mZslStreamId; 223} 224 225int ZslProcessor::getReprocessStreamId() const { 226 Mutex::Autolock l(mInputMutex); 227 return mZslReprocessStreamId; 228} 229 230status_t ZslProcessor::pushToReprocess(int32_t requestId) { 231 ALOGV("%s: Send in reprocess request with id %d", 232 __FUNCTION__, requestId); 233 Mutex::Autolock l(mInputMutex); 234 status_t res; 235 sp<Camera2Client> client = mClient.promote(); 236 237 if (client == 0) return INVALID_OPERATION; 238 239 IF_ALOGV() { 240 dumpZslQueue(-1); 241 } 242 243 244 if (mZslQueueTail != mZslQueueHead) { 245 CameraMetadata request; 246 size_t index = mZslQueueTail; 247 while (request.isEmpty() && index != mZslQueueHead) { 248 request = mZslQueue[index].frame; 249 index = (index + 1) % kZslBufferDepth; 250 } 251 if (request.isEmpty()) { 252 ALOGV("%s: ZSL queue has no valid frames to send yet.", 253 __FUNCTION__); 254 return NOT_ENOUGH_DATA; 255 } 256 // Verify that the frame is reasonable for reprocessing 257 258 camera_metadata_entry_t entry; 259 entry = request.find(ANDROID_CONTROL_AE_STATE); 260 if (entry.count == 0) { 261 ALOGE("%s: ZSL queue frame has no AE state field!", 262 __FUNCTION__); 263 return BAD_VALUE; 264 } 265 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED && 266 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) { 267 ALOGV("%s: ZSL queue frame AE state is %d, need full capture", 268 __FUNCTION__, entry.data.u8[0]); 269 return NOT_ENOUGH_DATA; 270 } 271 272 buffer_handle_t *handle = 273 &(mZslQueue[index].buffer.mGraphicBuffer->handle); 274 275 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS; 276 res = request.update(ANDROID_REQUEST_TYPE, 277 &requestType, 1); 278 uint8_t inputStreams[1] = { mZslReprocessStreamId }; 279 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS, 280 inputStreams, 1); 281 uint8_t outputStreams[1] = { client->getCaptureStreamId() }; 282 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS, 283 outputStreams, 1); 284 res = request.update(ANDROID_REQUEST_ID, 285 &requestId, 1); 286 287 if (res != OK ) { 288 ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__); 289 return INVALID_OPERATION; 290 } 291 292 res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId, 293 handle, this); 294 if (res != OK) { 295 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)", 296 __FUNCTION__, strerror(-res), res); 297 return res; 298 } 299 300 res = client->getCameraDevice()->capture(request); 301 if (res != OK ) { 302 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)", 303 __FUNCTION__, strerror(-res), res); 304 return res; 305 } 306 307 mState = LOCKED; 308 } else { 309 ALOGV("%s: No ZSL buffers yet", __FUNCTION__); 310 return NOT_ENOUGH_DATA; 311 } 312 return OK; 313} 314 315void ZslProcessor::dump(int fd, const Vector<String16>& args) const { 316 Mutex::Autolock l(mInputMutex); 317 dumpZslQueue(fd); 318} 319 320bool ZslProcessor::threadLoop() { 321 status_t res; 322 323 { 324 Mutex::Autolock l(mInputMutex); 325 while (!mZslBufferAvailable) { 326 res = mZslBufferAvailableSignal.waitRelative(mInputMutex, 327 kWaitDuration); 328 if (res == TIMED_OUT) return true; 329 } 330 mZslBufferAvailable = false; 331 } 332 333 do { 334 sp<Camera2Client> client = mClient.promote(); 335 if (client == 0) return false; 336 res = processNewZslBuffer(client); 337 } while (res == OK); 338 339 return true; 340} 341 342status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) { 343 ATRACE_CALL(); 344 status_t res; 345 346 ALOGVV("Trying to get next buffer"); 347 BufferItemConsumer::BufferItem item; 348 res = mZslConsumer->acquireBuffer(&item); 349 if (res != OK) { 350 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 351 ALOGE("%s: Camera %d: Error receiving ZSL image buffer: " 352 "%s (%d)", __FUNCTION__, 353 client->getCameraId(), strerror(-res), res); 354 } else { 355 ALOGVV(" No buffer"); 356 } 357 return res; 358 } 359 360 Mutex::Autolock l(mInputMutex); 361 362 if (mState == LOCKED) { 363 ALOGVV("In capture, discarding new ZSL buffers"); 364 mZslConsumer->releaseBuffer(item); 365 return OK; 366 } 367 368 ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail); 369 370 if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) { 371 ALOGVV("Releasing oldest buffer"); 372 mZslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer); 373 mZslQueue.replaceAt(mZslQueueTail); 374 mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth; 375 } 376 377 ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead); 378 379 queueHead.buffer = item; 380 queueHead.frame.release(); 381 382 mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth; 383 384 ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp); 385 386 findMatchesLocked(); 387 388 return OK; 389} 390 391void ZslProcessor::findMatchesLocked() { 392 ALOGVV("Scanning"); 393 for (size_t i = 0; i < mZslQueue.size(); i++) { 394 ZslPair &queueEntry = mZslQueue.editItemAt(i); 395 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 396 IF_ALOGV() { 397 camera_metadata_entry_t entry; 398 nsecs_t frameTimestamp = 0; 399 if (!queueEntry.frame.isEmpty()) { 400 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 401 frameTimestamp = entry.data.i64[0]; 402 } 403 ALOGVV(" %d: b: %lld\tf: %lld", i, 404 bufferTimestamp, frameTimestamp ); 405 } 406 if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) { 407 // Have buffer, no matching frame. Look for one 408 for (size_t j = 0; j < mFrameList.size(); j++) { 409 bool match = false; 410 CameraMetadata &frame = mFrameList.editItemAt(j); 411 if (!frame.isEmpty()) { 412 camera_metadata_entry_t entry; 413 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 414 if (entry.count == 0) { 415 ALOGE("%s: Can't find timestamp in frame!", 416 __FUNCTION__); 417 continue; 418 } 419 nsecs_t frameTimestamp = entry.data.i64[0]; 420 if (bufferTimestamp == frameTimestamp) { 421 ALOGVV("%s: Found match %lld", __FUNCTION__, 422 frameTimestamp); 423 match = true; 424 } else { 425 int64_t delta = abs(bufferTimestamp - frameTimestamp); 426 if ( delta < 1000000) { 427 ALOGVV("%s: Found close match %lld (delta %lld)", 428 __FUNCTION__, bufferTimestamp, delta); 429 match = true; 430 } 431 } 432 } 433 if (match) { 434 queueEntry.frame.acquire(frame); 435 break; 436 } 437 } 438 } 439 } 440} 441 442void ZslProcessor::dumpZslQueue(int fd) const { 443 String8 header("ZSL queue contents:"); 444 String8 indent(" "); 445 ALOGV("%s", header.string()); 446 if (fd != -1) { 447 header = indent + header + "\n"; 448 write(fd, header.string(), header.size()); 449 } 450 for (size_t i = 0; i < mZslQueue.size(); i++) { 451 const ZslPair &queueEntry = mZslQueue[i]; 452 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 453 camera_metadata_ro_entry_t entry; 454 nsecs_t frameTimestamp = 0; 455 int frameAeState = -1; 456 if (!queueEntry.frame.isEmpty()) { 457 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 458 if (entry.count > 0) frameTimestamp = entry.data.i64[0]; 459 entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE); 460 if (entry.count > 0) frameAeState = entry.data.u8[0]; 461 } 462 String8 result = 463 String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i, 464 bufferTimestamp, frameTimestamp, frameAeState); 465 ALOGV("%s", result.string()); 466 if (fd != -1) { 467 result = indent + result + "\n"; 468 write(fd, result.string(), result.size()); 469 } 470 471 } 472} 473 474}; // namespace camera2 475}; // namespace android 476