blob: 80c2b1f3b93018033bf7b093082f1f1ec8182c60 [file] [log] [blame]
Ari Hausman-Cohen73442152016-06-08 15:50:49 -07001/*
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
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070017#include "v4l2_camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070018
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070019#include <fcntl.h>
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070020#include <linux/videodev2.h>
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070021#include <sys/stat.h>
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070022#include <sys/types.h>
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070023
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070024#include <cstdlib>
25
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070026#include <camera/CameraMetadata.h>
27#include <hardware/camera3.h>
28
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070029#include "common.h"
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -070030#include "function_thread.h"
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070031#include "metadata/metadata_common.h"
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070032#include "stream_format.h"
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070033#include "v4l2_metadata_factory.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070034
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070035#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
36
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070037namespace v4l2_camera_hal {
38
Ari Hausman-Cohendde80172016-07-01 16:20:36 -070039// Helper function for managing metadata.
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070040static std::vector<int32_t> getMetadataKeys(const camera_metadata_t* metadata) {
Ari Hausman-Cohendde80172016-07-01 16:20:36 -070041 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
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070051V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) {
52 HAL_LOG_ENTER();
53
Ari Hausman-Cohen9e6fd982016-08-02 16:29:53 -070054 std::shared_ptr<V4L2Wrapper> v4l2_wrapper(V4L2Wrapper::NewV4L2Wrapper(path));
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -070055 if (!v4l2_wrapper) {
56 HAL_LOGE("Failed to initialize V4L2 wrapper.");
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070057 return nullptr;
58 }
59
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070060 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));
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070068}
69
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070070V4L2Camera::V4L2Camera(int id,
71 std::shared_ptr<V4L2Wrapper> v4l2_wrapper,
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070072 std::unique_ptr<Metadata> metadata)
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070073 : default_camera_hal::Camera(id),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070074 device_(std::move(v4l2_wrapper)),
75 metadata_(std::move(metadata)),
76 max_input_streams_(0),
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -070077 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))) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070082 HAL_LOG_ENTER();
83}
84
85V4L2Camera::~V4L2Camera() {
86 HAL_LOG_ENTER();
87}
88
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070089int V4L2Camera::connect() {
90 HAL_LOG_ENTER();
91
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070092 if (connection_) {
Ari Hausman-Cohen9e6fd982016-08-02 16:29:53 -070093 HAL_LOGE("Already connected. Please disconnect and try again.");
94 return -EIO;
95 }
96
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070097 connection_.reset(new V4L2Wrapper::Connection(device_));
98 if (connection_->status()) {
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -070099 HAL_LOGE("Failed to connect to device.");
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700100 return connection_->status();
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700101 }
102
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700103 // TODO(b/29185945): confirm this is a supported device.
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700104 // This is checked by the HAL, but the device at |device_|'s path may
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700105 // 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)
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700109
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700110 // TODO(b/29158098): Inform service of any flashes that are no longer
111 // available because this camera is in use.
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700112 return 0;
113}
114
115void V4L2Camera::disconnect() {
116 HAL_LOG_ENTER();
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700117
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700118 connection_.reset();
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700119
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700120 // TODO(b/29158098): Inform service of any flashes that are available again
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700121 // because this camera is no longer in use.
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700122}
123
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700124int V4L2Camera::initStaticInfo(android::CameraMetadata* out) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700125 HAL_LOG_ENTER();
126
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700127 int res = metadata_->FillStaticMetadata(out);
128 if (res) {
129 HAL_LOGE("Failed to get static metadata.");
Ari Hausman-Cohendde80172016-07-01 16:20:36 -0700130 return res;
131 }
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700132
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700133 // Extract max streams for use in verifying stream configs.
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700134 res = SingleTagValue(
135 *out, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &max_input_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700136 if (res) {
137 HAL_LOGE("Failed to get max num input streams from static metadata.");
138 return res;
139 }
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700140 res = SingleTagValue(
141 *out, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700142 if (res) {
143 HAL_LOGE("Failed to get max num output streams from static metadata.");
Ari Hausman-Cohendde80172016-07-01 16:20:36 -0700144 return res;
145 }
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700146
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700147 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700148}
149
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700150int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) {
151 HAL_LOG_ENTER();
152
153 return metadata_->GetRequestTemplate(type, out);
154}
155
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700156void V4L2Camera::initDeviceInfo(camera_info_t* info) {
157 HAL_LOG_ENTER();
158
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700159 // TODO(b/31044975): move this into device interface.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700160 // For now, just constants.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700161 info->resource_cost = 100;
162 info->conflicting_devices = nullptr;
163 info->conflicting_devices_length = 0;
164}
165
166int V4L2Camera::initDevice() {
167 HAL_LOG_ENTER();
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700168
169 // Start the buffer enqueue/dequeue threads if they're not already running.
170 if (!buffer_enqueuer_->isRunning()) {
171 android::status_t res = buffer_enqueuer_->run("Enqueue buffers");
172 if (res != android::OK) {
173 HAL_LOGE("Failed to start buffer enqueue thread: %d", res);
174 return -ENODEV;
175 }
176 }
177 if (!buffer_dequeuer_->isRunning()) {
178 android::status_t res = buffer_dequeuer_->run("Dequeue buffers");
179 if (res != android::OK) {
180 HAL_LOGE("Failed to start buffer dequeue thread: %d", res);
181 return -ENODEV;
182 }
183 }
184
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700185 return 0;
186}
187
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700188int V4L2Camera::enqueueRequest(
189 std::shared_ptr<default_camera_hal::CaptureRequest> request) {
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700190 HAL_LOG_ENTER();
191
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700192 // Assume request validated before calling this function.
193 // (For now, always exactly 1 output buffer, no inputs).
194
195 {
196 std::lock_guard<std::mutex> guard(request_queue_lock_);
197 request_queue_.push(request);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700198 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700199 requests_available_.notify_one();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700200
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700201 return 0;
202}
203
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700204std::shared_ptr<default_camera_hal::CaptureRequest>
205V4L2Camera::dequeueRequest() {
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700206 std::unique_lock<std::mutex> lock(request_queue_lock_);
207 while (request_queue_.empty()) {
208 requests_available_.wait(lock);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700209 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700210
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700211 std::shared_ptr<default_camera_hal::CaptureRequest> request =
212 request_queue_.front();
213 request_queue_.pop();
214 return request;
215}
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700216
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700217bool V4L2Camera::enqueueRequestBuffers() {
218 // Get a request from the queue (blocks this thread until one is available).
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700219 std::shared_ptr<default_camera_hal::CaptureRequest> request =
220 dequeueRequest();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700221
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700222 // Assume request validated before being added to the queue
223 // (For now, always exactly 1 output buffer, no inputs).
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700224
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700225 // Setting and getting settings are best effort here,
226 // since there's no way to know through V4L2 exactly what
227 // settings are used for a buffer unless we were to enqueue them
228 // one at a time, which would be too slow.
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700229
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700230 // Set the requested settings
231 int res = metadata_->SetRequestSettings(request->settings);
232 if (res) {
233 HAL_LOGE("Failed to set settings.");
234 completeRequest(request, res);
235 return true;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700236 }
237
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700238 // Actually enqueue the buffer for capture.
239 res = device_->EnqueueBuffer(&request->output_buffers[0]);
240 if (res) {
241 HAL_LOGE("Device failed to enqueue buffer.");
242 completeRequest(request, res);
243 return true;
244 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700245
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700246 // Replace the requested settings with a snapshot of
247 // the used settings/state immediately after enqueue.
248 res = metadata_->FillResultMetadata(&request->settings);
249 if (res) {
250 HAL_LOGE("Failed to fill result metadata.");
251 completeRequest(request, res);
252 return true;
253 }
254
255 // Make sure the stream is on (no effect if already on).
256 res = device_->StreamOn();
257 if (res) {
258 HAL_LOGE("Device failed to turn on stream.");
259 completeRequest(request, res);
260 return true;
261 }
262
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700263 {
264 std::lock_guard<std::mutex> guard(in_flight_lock_);
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700265 in_flight_.push(request);
266 }
267 buffers_in_flight_.notify_one();
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700268
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700269 return true;
270}
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700271
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700272bool V4L2Camera::dequeueRequestBuffers() {
273 std::unique_lock<std::mutex> lock(in_flight_lock_);
274 while (in_flight_.empty()) {
275 buffers_in_flight_.wait(lock);
276 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700277
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700278 std::shared_ptr<default_camera_hal::CaptureRequest> request =
279 in_flight_.front();
280 in_flight_.pop();
281
282 lock.unlock();
283
284 // Dequeue the buffer. For now, since each request has only 1 buffer,
285 // and the in_flight_lock_ is held while enqueueing and dequeuing
286 // from the device, just assume that the dequeued buffer corresponds
287 // to the dequeued request.
288 // TODO(b/31657008): in_flight_ should map buffer handles to requests;
289 // this consumer should just dequeue whatever it gets, then match
290 // that to a handle.
291 v4l2_buffer result_buffer;
292 int res = device_->DequeueBuffer(&result_buffer);
293 if (res) {
294 HAL_LOGE("Device failed to dequeue buffer.");
295 completeRequest(request, res);
296 return true;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700297 }
298
299 completeRequest(request, 0);
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700300 return true;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700301}
302
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700303bool V4L2Camera::isSupportedStreamSet(default_camera_hal::Stream** streams,
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700304 int count,
305 uint32_t mode) {
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700306 HAL_LOG_ENTER();
307
308 if (mode != CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE) {
309 HAL_LOGE("Unsupported stream configuration mode: %d", mode);
310 return false;
311 }
312
313 // This should be checked by the caller, but put here as a sanity check.
314 if (count < 1) {
315 HAL_LOGE("Must request at least 1 stream");
316 return false;
317 }
318
319 // Count the number of streams of each type.
320 int32_t num_input = 0;
321 int32_t num_raw = 0;
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700322 int32_t num_stalling = 0;
323 int32_t num_non_stalling = 0;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700324 for (int i = 0; i < count; ++i) {
325 default_camera_hal::Stream* stream = streams[i];
326
327 if (stream->isInputType()) {
328 ++num_input;
329 }
330
331 if (stream->isOutputType()) {
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700332 StreamFormat format(*stream);
333 switch (format.Category()) {
334 case kFormatCategoryRaw:
335 ++num_raw;
336 case kFormatCategoryStalling:
337 ++num_stalling;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700338 break;
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700339 case kFormatCategoryNonStalling:
340 ++num_non_stalling;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700341 break;
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700342 case kFormatCategoryUnknown: // Fall through.
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700343 default:
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700344 HAL_LOGE(
345 "Unsupported format for stream %d: %d", i, stream->getFormat());
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700346 return false;
347 }
348 }
349 }
350
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700351 if (num_input > max_input_streams_ || num_raw > max_output_streams_[0] ||
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700352 num_non_stalling > max_output_streams_[1] ||
353 num_stalling > max_output_streams_[2]) {
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700354 HAL_LOGE(
355 "Invalid stream configuration: %d input, %d RAW, %d non-stalling, "
356 "%d stalling (max supported: %d input, %d RAW, %d non-stalling, "
357 "%d stalling)",
358 max_input_streams_,
359 max_output_streams_[0],
360 max_output_streams_[1],
361 max_output_streams_[2],
362 num_input,
363 num_raw,
364 num_non_stalling,
365 num_stalling);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700366 return false;
367 }
368
369 // TODO(b/29939583): The above logic should be all that's necessary,
370 // but V4L2 doesn't actually support more than 1 stream at a time. So for now,
371 // if not all streams are the same format and size, error. Note that this
372 // means the HAL is not spec-compliant; the requested streams are technically
373 // valid and it is not technically allowed to error once it has reached this
374 // point.
375 int format = streams[0]->getFormat();
376 uint32_t width = streams[0]->getWidth();
377 uint32_t height = streams[0]->getHeight();
378 for (int i = 1; i < count; ++i) {
379 const default_camera_hal::Stream* stream = streams[i];
380 if (stream->getFormat() != format || stream->getWidth() != width ||
381 stream->getHeight() != height) {
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700382 HAL_LOGE(
383 "V4L2 only supports 1 stream configuration at a time "
384 "(stream 0 is format %d, width %u, height %u, "
385 "stream %d is format %d, width %u, height %u).",
386 format,
387 width,
388 height,
389 i,
390 stream->getFormat(),
391 stream->getWidth(),
392 stream->getHeight());
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700393 return false;
394 }
395 }
396
397 return true;
398}
399
400int V4L2Camera::setupStream(default_camera_hal::Stream* stream,
401 uint32_t* max_buffers) {
402 HAL_LOG_ENTER();
403
404 if (stream->getRotation() != CAMERA3_STREAM_ROTATION_0) {
405 HAL_LOGE("Rotation %d not supported", stream->getRotation());
406 return -EINVAL;
407 }
408
409 // Doesn't matter what was requested, we always use dataspace V0_JFIF.
410 // Note: according to camera3.h, this isn't allowed, but etalvala@google.com
411 // claims it's underdocumented; the implementation lets the HAL overwrite it.
412 stream->setDataSpace(HAL_DATASPACE_V0_JFIF);
413
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700414 int res = device_->StreamOff();
415 if (res) {
416 HAL_LOGE("Device failed to turn off stream for reconfiguration.");
417 return -ENODEV;
418 }
419
420 res = device_->SetFormat(*stream, max_buffers);
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700421 if (res) {
422 HAL_LOGE("Failed to set device to correct format for stream.");
423 return res;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700424 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700425 // Sanity check.
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700426 if (*max_buffers < 1) {
427 HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.",
428 *max_buffers);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700429 return -ENODEV;
430 }
431
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700432 return 0;
433}
434
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700435bool V4L2Camera::isValidRequest(
436 const default_camera_hal::CaptureRequest& request) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700437 HAL_LOG_ENTER();
438
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700439 if (request.input_buffer != nullptr) {
440 HAL_LOGE("Input buffer reprocessing not implemented.");
441 return false;
442 } else if (request.output_buffers.size() > 1) {
443 HAL_LOGE("Only 1 output buffer allowed per request.");
444 return false;
445 } else if (!metadata_->IsValidRequest(request.settings)) {
446 HAL_LOGE("Invalid request settings.");
447 return false;
448 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700449
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700450 return true;
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700451}
452
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700453} // namespace v4l2_camera_hal