blob: 62d790e5d78ef0524957e1a18a9eb6453056fe20 [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
Sergii Piatakov2ad591f2018-08-03 11:41:06 +030017//#define LOG_NDEBUG 0
18#define LOG_TAG "V4L2Camera"
19
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070020#include "v4l2_camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070021
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070022#include <fcntl.h>
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070023#include <linux/videodev2.h>
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070024#include <sys/stat.h>
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070025#include <sys/types.h>
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070026
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070027#include <cstdlib>
28
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070029#include <camera/CameraMetadata.h>
30#include <hardware/camera3.h>
31
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070032#include "common.h"
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -070033#include "function_thread.h"
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070034#include "metadata/metadata_common.h"
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070035#include "stream_format.h"
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070036#include "v4l2_metadata_factory.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070037
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070038#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
39
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070040namespace v4l2_camera_hal {
41
Ari Hausman-Cohendde80172016-07-01 16:20:36 -070042// Helper function for managing metadata.
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070043static std::vector<int32_t> getMetadataKeys(const camera_metadata_t* metadata) {
Ari Hausman-Cohendde80172016-07-01 16:20:36 -070044 std::vector<int32_t> keys;
45 size_t num_entries = get_camera_metadata_entry_count(metadata);
46 for (size_t i = 0; i < num_entries; ++i) {
47 camera_metadata_ro_entry_t entry;
48 get_camera_metadata_ro_entry(metadata, i, &entry);
49 keys.push_back(entry.tag);
50 }
51 return keys;
52}
53
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070054V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) {
55 HAL_LOG_ENTER();
56
Ari Hausman-Cohen9e6fd982016-08-02 16:29:53 -070057 std::shared_ptr<V4L2Wrapper> v4l2_wrapper(V4L2Wrapper::NewV4L2Wrapper(path));
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -070058 if (!v4l2_wrapper) {
59 HAL_LOGE("Failed to initialize V4L2 wrapper.");
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070060 return nullptr;
61 }
62
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070063 std::unique_ptr<Metadata> metadata;
64 int res = GetV4L2Metadata(v4l2_wrapper, &metadata);
65 if (res) {
66 HAL_LOGE("Failed to initialize V4L2 metadata: %d", res);
67 return nullptr;
68 }
69
70 return new V4L2Camera(id, std::move(v4l2_wrapper), std::move(metadata));
Ari Hausman-Cohen681eaa22016-07-21 16:28:17 -070071}
72
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -070073V4L2Camera::V4L2Camera(int id,
74 std::shared_ptr<V4L2Wrapper> v4l2_wrapper,
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070075 std::unique_ptr<Metadata> metadata)
Ari Hausman-Cohen49925842016-06-21 14:07:58 -070076 : default_camera_hal::Camera(id),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070077 device_(std::move(v4l2_wrapper)),
78 metadata_(std::move(metadata)),
79 max_input_streams_(0),
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -070080 max_output_streams_({{0, 0, 0}}),
81 buffer_enqueuer_(new FunctionThread(
82 std::bind(&V4L2Camera::enqueueRequestBuffers, this))),
83 buffer_dequeuer_(new FunctionThread(
84 std::bind(&V4L2Camera::dequeueRequestBuffers, this))) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070085 HAL_LOG_ENTER();
86}
87
88V4L2Camera::~V4L2Camera() {
89 HAL_LOG_ENTER();
90}
91
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070092int V4L2Camera::connect() {
93 HAL_LOG_ENTER();
94
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070095 if (connection_) {
Ari Hausman-Cohen9e6fd982016-08-02 16:29:53 -070096 HAL_LOGE("Already connected. Please disconnect and try again.");
97 return -EIO;
98 }
99
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700100 connection_.reset(new V4L2Wrapper::Connection(device_));
101 if (connection_->status()) {
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700102 HAL_LOGE("Failed to connect to device.");
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700103 return connection_->status();
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700104 }
105
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700106 // TODO(b/29185945): confirm this is a supported device.
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700107 // This is checked by the HAL, but the device at |device_|'s path may
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700108 // not be the same one that was there when the HAL was loaded.
109 // (Alternatively, better hotplugging support may make this unecessary
110 // by disabling cameras that get disconnected and checking newly connected
111 // cameras, so connect() is never called on an unsupported camera)
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700112
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700113 // TODO(b/29158098): Inform service of any flashes that are no longer
114 // available because this camera is in use.
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700115 return 0;
116}
117
118void V4L2Camera::disconnect() {
119 HAL_LOG_ENTER();
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700120
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700121 connection_.reset();
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700122
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700123 // TODO(b/29158098): Inform service of any flashes that are available again
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700124 // because this camera is no longer in use.
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700125}
126
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800127int V4L2Camera::flushBuffers() {
128 HAL_LOG_ENTER();
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700129 return device_->StreamOff();
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800130}
131
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700132int V4L2Camera::initStaticInfo(android::CameraMetadata* out) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700133 HAL_LOG_ENTER();
134
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700135 int res = metadata_->FillStaticMetadata(out);
136 if (res) {
137 HAL_LOGE("Failed to get static metadata.");
Ari Hausman-Cohendde80172016-07-01 16:20:36 -0700138 return res;
139 }
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700140
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700141 // Extract max streams for use in verifying stream configs.
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700142 res = SingleTagValue(
143 *out, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &max_input_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700144 if (res) {
145 HAL_LOGE("Failed to get max num input streams from static metadata.");
146 return res;
147 }
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700148 res = SingleTagValue(
149 *out, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700150 if (res) {
151 HAL_LOGE("Failed to get max num output streams from static metadata.");
Ari Hausman-Cohendde80172016-07-01 16:20:36 -0700152 return res;
153 }
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700154
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700155 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700156}
157
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700158int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) {
159 HAL_LOG_ENTER();
160
161 return metadata_->GetRequestTemplate(type, out);
162}
163
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700164void V4L2Camera::initDeviceInfo(camera_info_t* info) {
165 HAL_LOG_ENTER();
166
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700167 // TODO(b/31044975): move this into device interface.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700168 // For now, just constants.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700169 info->resource_cost = 100;
170 info->conflicting_devices = nullptr;
171 info->conflicting_devices_length = 0;
172}
173
174int V4L2Camera::initDevice() {
175 HAL_LOG_ENTER();
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700176
177 // Start the buffer enqueue/dequeue threads if they're not already running.
178 if (!buffer_enqueuer_->isRunning()) {
179 android::status_t res = buffer_enqueuer_->run("Enqueue buffers");
180 if (res != android::OK) {
181 HAL_LOGE("Failed to start buffer enqueue thread: %d", res);
182 return -ENODEV;
183 }
184 }
185 if (!buffer_dequeuer_->isRunning()) {
186 android::status_t res = buffer_dequeuer_->run("Dequeue buffers");
187 if (res != android::OK) {
188 HAL_LOGE("Failed to start buffer dequeue thread: %d", res);
189 return -ENODEV;
190 }
191 }
192
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700193 return 0;
194}
195
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700196int V4L2Camera::enqueueRequest(
197 std::shared_ptr<default_camera_hal::CaptureRequest> request) {
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700198 HAL_LOG_ENTER();
199
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700200 // Assume request validated before calling this function.
201 // (For now, always exactly 1 output buffer, no inputs).
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700202 {
203 std::lock_guard<std::mutex> guard(request_queue_lock_);
204 request_queue_.push(request);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800205 requests_available_.notify_one();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700206 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700207
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700208 return 0;
209}
210
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700211std::shared_ptr<default_camera_hal::CaptureRequest>
212V4L2Camera::dequeueRequest() {
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700213 std::unique_lock<std::mutex> lock(request_queue_lock_);
214 while (request_queue_.empty()) {
215 requests_available_.wait(lock);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700216 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700217
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700218 std::shared_ptr<default_camera_hal::CaptureRequest> request =
219 request_queue_.front();
220 request_queue_.pop();
221 return request;
222}
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700223
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700224bool V4L2Camera::enqueueRequestBuffers() {
225 // Get a request from the queue (blocks this thread until one is available).
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700226 std::shared_ptr<default_camera_hal::CaptureRequest> request =
227 dequeueRequest();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700228
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700229 // Assume request validated before being added to the queue
230 // (For now, always exactly 1 output buffer, no inputs).
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700231
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700232 // Setting and getting settings are best effort here,
233 // since there's no way to know through V4L2 exactly what
234 // settings are used for a buffer unless we were to enqueue them
235 // one at a time, which would be too slow.
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700236
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700237 // Set the requested settings
238 int res = metadata_->SetRequestSettings(request->settings);
239 if (res) {
240 HAL_LOGE("Failed to set settings.");
241 completeRequest(request, res);
242 return true;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700243 }
244
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700245 // Replace the requested settings with a snapshot of
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800246 // the used settings/state immediately before enqueue.
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700247 res = metadata_->FillResultMetadata(&request->settings);
248 if (res) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800249 // Note: since request is a shared pointer, this may happen if another
250 // thread has already decided to complete the request (e.g. via flushing),
251 // since that locks the metadata (in that case, this failing is fine,
252 // and completeRequest will simply do nothing).
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700253 HAL_LOGE("Failed to fill result metadata.");
254 completeRequest(request, res);
255 return true;
256 }
257
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800258 // Actually enqueue the buffer for capture.
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700259 res = device_->EnqueueRequest(request);
260 if (res) {
261 HAL_LOGE("Device failed to enqueue buffer.");
262 completeRequest(request, res);
263 return true;
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700264 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700265
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700266 // Make sure the stream is on (no effect if already on).
267 res = device_->StreamOn();
268 if (res) {
269 HAL_LOGE("Device failed to turn on stream.");
270 // Don't really want to send an error for only the request here,
271 // since this is a full device error.
272 // TODO: Should trigger full flush.
273 return true;
274 }
275
276 std::unique_lock<std::mutex> lock(in_flight_lock_);
277 in_flight_buffer_count_++;
278 buffers_in_flight_.notify_one();
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700279 return true;
280}
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700281
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700282bool V4L2Camera::dequeueRequestBuffers() {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800283 // Dequeue a buffer.
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700284 std::shared_ptr<default_camera_hal::CaptureRequest> request;
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900285 int res;
286
287 {
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700288 std::unique_lock<std::mutex> lock(in_flight_lock_);
289 res = device_->DequeueRequest(&request);
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900290 if (!res) {
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700291 if (request) {
292 completeRequest(request, res);
293 in_flight_buffer_count_--;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800294 }
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900295 return true;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800296 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700297 }
298
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900299 if (res == -EAGAIN) {
300 // EAGAIN just means nothing to dequeue right now.
301 // Wait until something is available before looping again.
302 std::unique_lock<std::mutex> lock(in_flight_lock_);
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700303 while (in_flight_buffer_count_ == 0) {
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900304 buffers_in_flight_.wait(lock);
305 }
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800306 } else {
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900307 HAL_LOGW("Device failed to dequeue buffer: %d", res);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800308 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700309 return true;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700310}
311
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800312bool V4L2Camera::validateDataspacesAndRotations(
313 const camera3_stream_configuration_t* stream_config) {
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700314 HAL_LOG_ENTER();
315
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800316 for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
317 if (stream_config->streams[i]->rotation != CAMERA3_STREAM_ROTATION_0) {
318 HAL_LOGV("Rotation %d for stream %d not supported",
319 stream_config->streams[i]->rotation,
320 i);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700321 return false;
322 }
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800323 // Accept all dataspaces, as it will just be overwritten below anyways.
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700324 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700325 return true;
326}
327
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800328int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) {
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700329 HAL_LOG_ENTER();
330
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800331 std::lock_guard<std::mutex> guard(in_flight_lock_);
332 // The framework should be enforcing this, but doesn't hurt to be safe.
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700333 if (device_->GetInFlightBufferCount() != 0) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800334 HAL_LOGE("Can't set device format while frames are in flight.");
335 return -EINVAL;
336 }
Prashanth Swaminathan28e0f762017-04-27 11:32:11 -0700337 in_flight_buffer_count_ = 0;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800338
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800339 // stream_config should have been validated; assume at least 1 stream.
340 camera3_stream_t* stream = stream_config->streams[0];
341 int format = stream->format;
342 uint32_t width = stream->width;
343 uint32_t height = stream->height;
344
345 if (stream_config->num_streams > 1) {
346 // TODO(b/29939583): V4L2 doesn't actually support more than 1
347 // stream at a time. If not all streams are the same format
348 // and size, error. Note that this means the HAL is not spec-compliant.
349 // Technically, this error should be thrown during validation, but
350 // since it isn't a spec-valid error validation isn't set up to check it.
351 for (uint32_t i = 1; i < stream_config->num_streams; ++i) {
352 stream = stream_config->streams[i];
353 if (stream->format != format || stream->width != width ||
354 stream->height != height) {
355 HAL_LOGE(
356 "V4L2 only supports 1 stream configuration at a time "
357 "(stream 0 is format %d, width %u, height %u, "
358 "stream %d is format %d, width %u, height %u).",
359 format,
360 width,
361 height,
362 i,
363 stream->format,
364 stream->width,
365 stream->height);
366 return -EINVAL;
367 }
368 }
369 }
370
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800371 // Ensure the stream is off.
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700372 int res = device_->StreamOff();
373 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800374 HAL_LOGE("Device failed to turn off stream for reconfiguration: %d.", res);
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700375 return -ENODEV;
376 }
377
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800378 StreamFormat stream_format(format, width, height);
379 uint32_t max_buffers = 0;
380 res = device_->SetFormat(stream_format, &max_buffers);
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700381 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800382 HAL_LOGE("Failed to set device to correct format for stream: %d.", res);
383 return -ENODEV;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700384 }
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800385
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700386 // Sanity check.
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800387 if (max_buffers < 1) {
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700388 HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.",
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800389 max_buffers);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700390 return -ENODEV;
391 }
392
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800393 // Set all the streams dataspaces, usages, and max buffers.
394 for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
395 stream = stream_config->streams[i];
396
Jaesung Chung6e8afea2017-11-15 09:30:41 +0900397 // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format.
398 if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
399 stream->format = HAL_PIXEL_FORMAT_RGBA_8888;
400 }
401
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800402 // Max buffers as reported by the device.
403 stream->max_buffers = max_buffers;
404
405 // Usage: currently using sw graphics.
406 switch (stream->stream_type) {
407 case CAMERA3_STREAM_INPUT:
408 stream->usage = GRALLOC_USAGE_SW_READ_OFTEN;
409 break;
410 case CAMERA3_STREAM_OUTPUT:
411 stream->usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
412 break;
413 case CAMERA3_STREAM_BIDIRECTIONAL:
414 stream->usage =
415 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
416 break;
417 default:
418 // nothing to do.
419 break;
420 }
421
422 // Doesn't matter what was requested, we always use dataspace V0_JFIF.
423 // Note: according to camera3.h, this isn't allowed, but the camera
424 // framework team claims it's underdocumented; the implementation lets the
425 // HAL overwrite it. If this is changed, change the validation above.
426 stream->data_space = HAL_DATASPACE_V0_JFIF;
427 }
428
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700429 return 0;
430}
431
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800432bool V4L2Camera::isValidRequestSettings(
433 const android::CameraMetadata& settings) {
434 if (!metadata_->IsValidRequest(settings)) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700435 HAL_LOGE("Invalid request settings.");
436 return false;
437 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700438 return true;
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700439}
440
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700441} // namespace v4l2_camera_hal