1/* 2 * Copyright 2016 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#include "v4l2_camera.h" 18 19#include <fcntl.h> 20#include <linux/videodev2.h> 21#include <sys/stat.h> 22#include <sys/types.h> 23 24#include <cstdlib> 25 26#include <camera/CameraMetadata.h> 27#include <hardware/camera3.h> 28 29#include "common.h" 30#include "function_thread.h" 31#include "metadata/metadata_common.h" 32#include "stream_format.h" 33#include "v4l2_metadata_factory.h" 34 35#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) 36 37namespace v4l2_camera_hal { 38 39// Helper function for managing metadata. 40static std::vector<int32_t> getMetadataKeys(const camera_metadata_t* metadata) { 41 std::vector<int32_t> keys; 42 size_t num_entries = get_camera_metadata_entry_count(metadata); 43 for (size_t i = 0; i < num_entries; ++i) { 44 camera_metadata_ro_entry_t entry; 45 get_camera_metadata_ro_entry(metadata, i, &entry); 46 keys.push_back(entry.tag); 47 } 48 return keys; 49} 50 51V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) { 52 HAL_LOG_ENTER(); 53 54 std::shared_ptr<V4L2Wrapper> v4l2_wrapper(V4L2Wrapper::NewV4L2Wrapper(path)); 55 if (!v4l2_wrapper) { 56 HAL_LOGE("Failed to initialize V4L2 wrapper."); 57 return nullptr; 58 } 59 60 std::unique_ptr<Metadata> metadata; 61 int res = GetV4L2Metadata(v4l2_wrapper, &metadata); 62 if (res) { 63 HAL_LOGE("Failed to initialize V4L2 metadata: %d", res); 64 return nullptr; 65 } 66 67 return new V4L2Camera(id, std::move(v4l2_wrapper), std::move(metadata)); 68} 69 70V4L2Camera::V4L2Camera(int id, 71 std::shared_ptr<V4L2Wrapper> v4l2_wrapper, 72 std::unique_ptr<Metadata> metadata) 73 : default_camera_hal::Camera(id), 74 device_(std::move(v4l2_wrapper)), 75 metadata_(std::move(metadata)), 76 max_input_streams_(0), 77 max_output_streams_({{0, 0, 0}}), 78 buffer_enqueuer_(new FunctionThread( 79 std::bind(&V4L2Camera::enqueueRequestBuffers, this))), 80 buffer_dequeuer_(new FunctionThread( 81 std::bind(&V4L2Camera::dequeueRequestBuffers, this))) { 82 HAL_LOG_ENTER(); 83} 84 85V4L2Camera::~V4L2Camera() { 86 HAL_LOG_ENTER(); 87} 88 89int V4L2Camera::connect() { 90 HAL_LOG_ENTER(); 91 92 if (connection_) { 93 HAL_LOGE("Already connected. Please disconnect and try again."); 94 return -EIO; 95 } 96 97 connection_.reset(new V4L2Wrapper::Connection(device_)); 98 if (connection_->status()) { 99 HAL_LOGE("Failed to connect to device."); 100 return connection_->status(); 101 } 102 103 // TODO(b/29185945): confirm this is a supported device. 104 // This is checked by the HAL, but the device at |device_|'s path may 105 // not be the same one that was there when the HAL was loaded. 106 // (Alternatively, better hotplugging support may make this unecessary 107 // by disabling cameras that get disconnected and checking newly connected 108 // cameras, so connect() is never called on an unsupported camera) 109 110 // TODO(b/29158098): Inform service of any flashes that are no longer 111 // available because this camera is in use. 112 return 0; 113} 114 115void V4L2Camera::disconnect() { 116 HAL_LOG_ENTER(); 117 118 connection_.reset(); 119 120 // TODO(b/29158098): Inform service of any flashes that are available again 121 // because this camera is no longer in use. 122} 123 124int V4L2Camera::flushBuffers() { 125 HAL_LOG_ENTER(); 126 return device_->StreamOff(); 127} 128 129int V4L2Camera::initStaticInfo(android::CameraMetadata* out) { 130 HAL_LOG_ENTER(); 131 132 int res = metadata_->FillStaticMetadata(out); 133 if (res) { 134 HAL_LOGE("Failed to get static metadata."); 135 return res; 136 } 137 138 // Extract max streams for use in verifying stream configs. 139 res = SingleTagValue( 140 *out, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &max_input_streams_); 141 if (res) { 142 HAL_LOGE("Failed to get max num input streams from static metadata."); 143 return res; 144 } 145 res = SingleTagValue( 146 *out, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams_); 147 if (res) { 148 HAL_LOGE("Failed to get max num output streams from static metadata."); 149 return res; 150 } 151 152 return 0; 153} 154 155int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) { 156 HAL_LOG_ENTER(); 157 158 return metadata_->GetRequestTemplate(type, out); 159} 160 161void V4L2Camera::initDeviceInfo(camera_info_t* info) { 162 HAL_LOG_ENTER(); 163 164 // TODO(b/31044975): move this into device interface. 165 // For now, just constants. 166 info->resource_cost = 100; 167 info->conflicting_devices = nullptr; 168 info->conflicting_devices_length = 0; 169} 170 171int V4L2Camera::initDevice() { 172 HAL_LOG_ENTER(); 173 174 // Start the buffer enqueue/dequeue threads if they're not already running. 175 if (!buffer_enqueuer_->isRunning()) { 176 android::status_t res = buffer_enqueuer_->run("Enqueue buffers"); 177 if (res != android::OK) { 178 HAL_LOGE("Failed to start buffer enqueue thread: %d", res); 179 return -ENODEV; 180 } 181 } 182 if (!buffer_dequeuer_->isRunning()) { 183 android::status_t res = buffer_dequeuer_->run("Dequeue buffers"); 184 if (res != android::OK) { 185 HAL_LOGE("Failed to start buffer dequeue thread: %d", res); 186 return -ENODEV; 187 } 188 } 189 190 return 0; 191} 192 193int V4L2Camera::enqueueRequest( 194 std::shared_ptr<default_camera_hal::CaptureRequest> request) { 195 HAL_LOG_ENTER(); 196 197 // Assume request validated before calling this function. 198 // (For now, always exactly 1 output buffer, no inputs). 199 { 200 std::lock_guard<std::mutex> guard(request_queue_lock_); 201 request_queue_.push(request); 202 requests_available_.notify_one(); 203 } 204 205 return 0; 206} 207 208std::shared_ptr<default_camera_hal::CaptureRequest> 209V4L2Camera::dequeueRequest() { 210 std::unique_lock<std::mutex> lock(request_queue_lock_); 211 while (request_queue_.empty()) { 212 requests_available_.wait(lock); 213 } 214 215 std::shared_ptr<default_camera_hal::CaptureRequest> request = 216 request_queue_.front(); 217 request_queue_.pop(); 218 return request; 219} 220 221bool V4L2Camera::enqueueRequestBuffers() { 222 // Get a request from the queue (blocks this thread until one is available). 223 std::shared_ptr<default_camera_hal::CaptureRequest> request = 224 dequeueRequest(); 225 226 // Assume request validated before being added to the queue 227 // (For now, always exactly 1 output buffer, no inputs). 228 229 // Setting and getting settings are best effort here, 230 // since there's no way to know through V4L2 exactly what 231 // settings are used for a buffer unless we were to enqueue them 232 // one at a time, which would be too slow. 233 234 // Set the requested settings 235 int res = metadata_->SetRequestSettings(request->settings); 236 if (res) { 237 HAL_LOGE("Failed to set settings."); 238 completeRequest(request, res); 239 return true; 240 } 241 242 // Replace the requested settings with a snapshot of 243 // the used settings/state immediately before enqueue. 244 res = metadata_->FillResultMetadata(&request->settings); 245 if (res) { 246 // Note: since request is a shared pointer, this may happen if another 247 // thread has already decided to complete the request (e.g. via flushing), 248 // since that locks the metadata (in that case, this failing is fine, 249 // and completeRequest will simply do nothing). 250 HAL_LOGE("Failed to fill result metadata."); 251 completeRequest(request, res); 252 return true; 253 } 254 255 // Actually enqueue the buffer for capture. 256 res = device_->EnqueueRequest(request); 257 if (res) { 258 HAL_LOGE("Device failed to enqueue buffer."); 259 completeRequest(request, res); 260 return true; 261 } 262 263 // Make sure the stream is on (no effect if already on). 264 res = device_->StreamOn(); 265 if (res) { 266 HAL_LOGE("Device failed to turn on stream."); 267 // Don't really want to send an error for only the request here, 268 // since this is a full device error. 269 // TODO: Should trigger full flush. 270 return true; 271 } 272 273 std::unique_lock<std::mutex> lock(in_flight_lock_); 274 in_flight_buffer_count_++; 275 buffers_in_flight_.notify_one(); 276 return true; 277} 278 279bool V4L2Camera::dequeueRequestBuffers() { 280 // Dequeue a buffer. 281 std::shared_ptr<default_camera_hal::CaptureRequest> request; 282 int res; 283 284 { 285 std::unique_lock<std::mutex> lock(in_flight_lock_); 286 res = device_->DequeueRequest(&request); 287 if (!res) { 288 if (request) { 289 completeRequest(request, res); 290 in_flight_buffer_count_--; 291 } 292 return true; 293 } 294 } 295 296 if (res == -EAGAIN) { 297 // EAGAIN just means nothing to dequeue right now. 298 // Wait until something is available before looping again. 299 std::unique_lock<std::mutex> lock(in_flight_lock_); 300 while (in_flight_buffer_count_ == 0) { 301 buffers_in_flight_.wait(lock); 302 } 303 } else { 304 HAL_LOGW("Device failed to dequeue buffer: %d", res); 305 } 306 return true; 307} 308 309bool V4L2Camera::validateDataspacesAndRotations( 310 const camera3_stream_configuration_t* stream_config) { 311 HAL_LOG_ENTER(); 312 313 for (uint32_t i = 0; i < stream_config->num_streams; ++i) { 314 if (stream_config->streams[i]->rotation != CAMERA3_STREAM_ROTATION_0) { 315 HAL_LOGV("Rotation %d for stream %d not supported", 316 stream_config->streams[i]->rotation, 317 i); 318 return false; 319 } 320 // Accept all dataspaces, as it will just be overwritten below anyways. 321 } 322 return true; 323} 324 325int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) { 326 HAL_LOG_ENTER(); 327 328 std::lock_guard<std::mutex> guard(in_flight_lock_); 329 // The framework should be enforcing this, but doesn't hurt to be safe. 330 if (device_->GetInFlightBufferCount() != 0) { 331 HAL_LOGE("Can't set device format while frames are in flight."); 332 return -EINVAL; 333 } 334 in_flight_buffer_count_ = 0; 335 336 // stream_config should have been validated; assume at least 1 stream. 337 camera3_stream_t* stream = stream_config->streams[0]; 338 int format = stream->format; 339 uint32_t width = stream->width; 340 uint32_t height = stream->height; 341 342 if (stream_config->num_streams > 1) { 343 // TODO(b/29939583): V4L2 doesn't actually support more than 1 344 // stream at a time. If not all streams are the same format 345 // and size, error. Note that this means the HAL is not spec-compliant. 346 // Technically, this error should be thrown during validation, but 347 // since it isn't a spec-valid error validation isn't set up to check it. 348 for (uint32_t i = 1; i < stream_config->num_streams; ++i) { 349 stream = stream_config->streams[i]; 350 if (stream->format != format || stream->width != width || 351 stream->height != height) { 352 HAL_LOGE( 353 "V4L2 only supports 1 stream configuration at a time " 354 "(stream 0 is format %d, width %u, height %u, " 355 "stream %d is format %d, width %u, height %u).", 356 format, 357 width, 358 height, 359 i, 360 stream->format, 361 stream->width, 362 stream->height); 363 return -EINVAL; 364 } 365 } 366 } 367 368 // Ensure the stream is off. 369 int res = device_->StreamOff(); 370 if (res) { 371 HAL_LOGE("Device failed to turn off stream for reconfiguration: %d.", res); 372 return -ENODEV; 373 } 374 375 StreamFormat stream_format(format, width, height); 376 uint32_t max_buffers = 0; 377 res = device_->SetFormat(stream_format, &max_buffers); 378 if (res) { 379 HAL_LOGE("Failed to set device to correct format for stream: %d.", res); 380 return -ENODEV; 381 } 382 383 // Sanity check. 384 if (max_buffers < 1) { 385 HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.", 386 max_buffers); 387 return -ENODEV; 388 } 389 390 // Set all the streams dataspaces, usages, and max buffers. 391 for (uint32_t i = 0; i < stream_config->num_streams; ++i) { 392 stream = stream_config->streams[i]; 393 394 // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format. 395 if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 396 stream->format = HAL_PIXEL_FORMAT_RGBA_8888; 397 } 398 399 // Max buffers as reported by the device. 400 stream->max_buffers = max_buffers; 401 402 // Usage: currently using sw graphics. 403 switch (stream->stream_type) { 404 case CAMERA3_STREAM_INPUT: 405 stream->usage = GRALLOC_USAGE_SW_READ_OFTEN; 406 break; 407 case CAMERA3_STREAM_OUTPUT: 408 stream->usage = GRALLOC_USAGE_SW_WRITE_OFTEN; 409 break; 410 case CAMERA3_STREAM_BIDIRECTIONAL: 411 stream->usage = 412 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; 413 break; 414 default: 415 // nothing to do. 416 break; 417 } 418 419 // Doesn't matter what was requested, we always use dataspace V0_JFIF. 420 // Note: according to camera3.h, this isn't allowed, but the camera 421 // framework team claims it's underdocumented; the implementation lets the 422 // HAL overwrite it. If this is changed, change the validation above. 423 stream->data_space = HAL_DATASPACE_V0_JFIF; 424 } 425 426 return 0; 427} 428 429bool V4L2Camera::isValidRequestSettings( 430 const android::CameraMetadata& settings) { 431 if (!metadata_->IsValidRequest(settings)) { 432 HAL_LOGE("Invalid request settings."); 433 return false; 434 } 435 return true; 436} 437 438} // namespace v4l2_camera_hal 439