blob: 22406c92cd5a25aa8bfd9e24c12716dc4d49c5e5 [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-Cohenc5a48522016-11-16 10:53:52 -0800124int V4L2Camera::flushBuffers() {
125 HAL_LOG_ENTER();
126
127 int res = device_->StreamOff();
128
129 // This is not strictly necessary, but prevents a buildup of aborted
130 // requests in the in_flight_ map. These should be cleared
131 // whenever the stream is turned off.
132 std::lock_guard<std::mutex> guard(in_flight_lock_);
133 in_flight_.clear();
134
135 return res;
136}
137
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700138int V4L2Camera::initStaticInfo(android::CameraMetadata* out) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700139 HAL_LOG_ENTER();
140
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700141 int res = metadata_->FillStaticMetadata(out);
142 if (res) {
143 HAL_LOGE("Failed to get 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-Cohenabbf9cc2016-08-23 11:59:59 -0700147 // Extract max streams for use in verifying stream configs.
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700148 res = SingleTagValue(
149 *out, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &max_input_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700150 if (res) {
151 HAL_LOGE("Failed to get max num input streams from static metadata.");
152 return res;
153 }
Ari Hausman-Cohen9430ad92016-08-24 14:00:32 -0700154 res = SingleTagValue(
155 *out, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams_);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700156 if (res) {
157 HAL_LOGE("Failed to get max num output streams from static metadata.");
Ari Hausman-Cohendde80172016-07-01 16:20:36 -0700158 return res;
159 }
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700160
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700161 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700162}
163
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700164int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) {
165 HAL_LOG_ENTER();
166
167 return metadata_->GetRequestTemplate(type, out);
168}
169
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700170void V4L2Camera::initDeviceInfo(camera_info_t* info) {
171 HAL_LOG_ENTER();
172
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700173 // TODO(b/31044975): move this into device interface.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700174 // For now, just constants.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700175 info->resource_cost = 100;
176 info->conflicting_devices = nullptr;
177 info->conflicting_devices_length = 0;
178}
179
180int V4L2Camera::initDevice() {
181 HAL_LOG_ENTER();
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700182
183 // Start the buffer enqueue/dequeue threads if they're not already running.
184 if (!buffer_enqueuer_->isRunning()) {
185 android::status_t res = buffer_enqueuer_->run("Enqueue buffers");
186 if (res != android::OK) {
187 HAL_LOGE("Failed to start buffer enqueue thread: %d", res);
188 return -ENODEV;
189 }
190 }
191 if (!buffer_dequeuer_->isRunning()) {
192 android::status_t res = buffer_dequeuer_->run("Dequeue buffers");
193 if (res != android::OK) {
194 HAL_LOGE("Failed to start buffer dequeue thread: %d", res);
195 return -ENODEV;
196 }
197 }
198
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700199 return 0;
200}
201
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700202int V4L2Camera::enqueueRequest(
203 std::shared_ptr<default_camera_hal::CaptureRequest> request) {
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700204 HAL_LOG_ENTER();
205
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700206 // Assume request validated before calling this function.
207 // (For now, always exactly 1 output buffer, no inputs).
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700208 {
209 std::lock_guard<std::mutex> guard(request_queue_lock_);
210 request_queue_.push(request);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800211 requests_available_.notify_one();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700212 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700213
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700214 return 0;
215}
216
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700217std::shared_ptr<default_camera_hal::CaptureRequest>
218V4L2Camera::dequeueRequest() {
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700219 std::unique_lock<std::mutex> lock(request_queue_lock_);
220 while (request_queue_.empty()) {
221 requests_available_.wait(lock);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700222 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700223
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700224 std::shared_ptr<default_camera_hal::CaptureRequest> request =
225 request_queue_.front();
226 request_queue_.pop();
227 return request;
228}
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700229
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700230bool V4L2Camera::enqueueRequestBuffers() {
231 // Get a request from the queue (blocks this thread until one is available).
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700232 std::shared_ptr<default_camera_hal::CaptureRequest> request =
233 dequeueRequest();
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700234
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700235 // Assume request validated before being added to the queue
236 // (For now, always exactly 1 output buffer, no inputs).
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700237
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700238 // Setting and getting settings are best effort here,
239 // since there's no way to know through V4L2 exactly what
240 // settings are used for a buffer unless we were to enqueue them
241 // one at a time, which would be too slow.
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700242
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700243 // Set the requested settings
244 int res = metadata_->SetRequestSettings(request->settings);
245 if (res) {
246 HAL_LOGE("Failed to set settings.");
247 completeRequest(request, res);
248 return true;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700249 }
250
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700251 // Replace the requested settings with a snapshot of
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800252 // the used settings/state immediately before enqueue.
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700253 res = metadata_->FillResultMetadata(&request->settings);
254 if (res) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800255 // Note: since request is a shared pointer, this may happen if another
256 // thread has already decided to complete the request (e.g. via flushing),
257 // since that locks the metadata (in that case, this failing is fine,
258 // and completeRequest will simply do nothing).
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700259 HAL_LOGE("Failed to fill result metadata.");
260 completeRequest(request, res);
261 return true;
262 }
263
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800264 // Actually enqueue the buffer for capture.
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700265 {
266 std::lock_guard<std::mutex> guard(in_flight_lock_);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800267
268 uint32_t index;
269 res = device_->EnqueueBuffer(&request->output_buffers[0], &index);
270 if (res) {
271 HAL_LOGE("Device failed to enqueue buffer.");
272 completeRequest(request, res);
273 return true;
274 }
275
276 // Make sure the stream is on (no effect if already on).
277 res = device_->StreamOn();
278 if (res) {
279 HAL_LOGE("Device failed to turn on stream.");
280 // Don't really want to send an error for only the request here,
281 // since this is a full device error.
282 // TODO: Should trigger full flush.
283 return true;
284 }
285
286 // Note: the request should be dequeued/flushed from the device
287 // before removal from in_flight_.
288 in_flight_.emplace(index, request);
289 buffers_in_flight_.notify_one();
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700290 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700291
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700292 return true;
293}
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700294
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700295bool V4L2Camera::dequeueRequestBuffers() {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800296 // Dequeue a buffer.
297 uint32_t result_index;
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900298 int res;
299
300 {
301 std::lock_guard<std::mutex> guard(in_flight_lock_);
302 res = device_->DequeueBuffer(&result_index);
303 if (!res) {
304 // Find the associated request and complete it.
305 auto index_request = in_flight_.find(result_index);
306 if (index_request != in_flight_.end()) {
307 completeRequest(index_request->second, 0);
308 in_flight_.erase(index_request);
309 } else {
310 HAL_LOGW(
311 "Dequeued non in-flight buffer index %d. "
312 "This buffer may have been flushed from the HAL but not the device.",
313 index_request->first);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800314 }
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900315 return true;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800316 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700317 }
318
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900319 if (res == -EAGAIN) {
320 // EAGAIN just means nothing to dequeue right now.
321 // Wait until something is available before looping again.
322 std::unique_lock<std::mutex> lock(in_flight_lock_);
323 while (in_flight_.empty()) {
324 buffers_in_flight_.wait(lock);
325 }
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800326 } else {
Jaesung Chung1fc9b612017-11-10 18:09:38 +0900327 HAL_LOGW("Device failed to dequeue buffer: %d", res);
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800328 }
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700329 return true;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700330}
331
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800332bool V4L2Camera::validateDataspacesAndRotations(
333 const camera3_stream_configuration_t* stream_config) {
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700334 HAL_LOG_ENTER();
335
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800336 for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
337 if (stream_config->streams[i]->rotation != CAMERA3_STREAM_ROTATION_0) {
338 HAL_LOGV("Rotation %d for stream %d not supported",
339 stream_config->streams[i]->rotation,
340 i);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700341 return false;
342 }
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800343 // Accept all dataspaces, as it will just be overwritten below anyways.
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700344 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700345 return true;
346}
347
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800348int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) {
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700349 HAL_LOG_ENTER();
350
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800351 std::lock_guard<std::mutex> guard(in_flight_lock_);
352 // The framework should be enforcing this, but doesn't hurt to be safe.
353 if (!in_flight_.empty()) {
354 HAL_LOGE("Can't set device format while frames are in flight.");
355 return -EINVAL;
356 }
357
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800358 // stream_config should have been validated; assume at least 1 stream.
359 camera3_stream_t* stream = stream_config->streams[0];
360 int format = stream->format;
361 uint32_t width = stream->width;
362 uint32_t height = stream->height;
363
364 if (stream_config->num_streams > 1) {
365 // TODO(b/29939583): V4L2 doesn't actually support more than 1
366 // stream at a time. If not all streams are the same format
367 // and size, error. Note that this means the HAL is not spec-compliant.
368 // Technically, this error should be thrown during validation, but
369 // since it isn't a spec-valid error validation isn't set up to check it.
370 for (uint32_t i = 1; i < stream_config->num_streams; ++i) {
371 stream = stream_config->streams[i];
372 if (stream->format != format || stream->width != width ||
373 stream->height != height) {
374 HAL_LOGE(
375 "V4L2 only supports 1 stream configuration at a time "
376 "(stream 0 is format %d, width %u, height %u, "
377 "stream %d is format %d, width %u, height %u).",
378 format,
379 width,
380 height,
381 i,
382 stream->format,
383 stream->width,
384 stream->height);
385 return -EINVAL;
386 }
387 }
388 }
389
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800390 // Ensure the stream is off.
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700391 int res = device_->StreamOff();
392 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800393 HAL_LOGE("Device failed to turn off stream for reconfiguration: %d.", res);
Ari Hausman-Cohen71cb8742016-09-22 11:12:00 -0700394 return -ENODEV;
395 }
396
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800397 StreamFormat stream_format(format, width, height);
398 uint32_t max_buffers = 0;
399 res = device_->SetFormat(stream_format, &max_buffers);
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700400 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800401 HAL_LOGE("Failed to set device to correct format for stream: %d.", res);
402 return -ENODEV;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700403 }
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800404
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700405 // Sanity check.
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800406 if (max_buffers < 1) {
Ari Hausman-Cohen660f8b82016-07-19 17:27:52 -0700407 HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.",
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800408 max_buffers);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700409 return -ENODEV;
410 }
411
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800412 // Set all the streams dataspaces, usages, and max buffers.
413 for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
414 stream = stream_config->streams[i];
415
Jaesung Chung6e8afea2017-11-15 09:30:41 +0900416 // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format.
417 if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
418 stream->format = HAL_PIXEL_FORMAT_RGBA_8888;
419 }
420
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800421 // Max buffers as reported by the device.
422 stream->max_buffers = max_buffers;
423
424 // Usage: currently using sw graphics.
425 switch (stream->stream_type) {
426 case CAMERA3_STREAM_INPUT:
427 stream->usage = GRALLOC_USAGE_SW_READ_OFTEN;
428 break;
429 case CAMERA3_STREAM_OUTPUT:
430 stream->usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
431 break;
432 case CAMERA3_STREAM_BIDIRECTIONAL:
433 stream->usage =
434 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
435 break;
436 default:
437 // nothing to do.
438 break;
439 }
440
441 // Doesn't matter what was requested, we always use dataspace V0_JFIF.
442 // Note: according to camera3.h, this isn't allowed, but the camera
443 // framework team claims it's underdocumented; the implementation lets the
444 // HAL overwrite it. If this is changed, change the validation above.
445 stream->data_space = HAL_DATASPACE_V0_JFIF;
446 }
447
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700448 return 0;
449}
450
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800451bool V4L2Camera::isValidRequestSettings(
452 const android::CameraMetadata& settings) {
453 if (!metadata_->IsValidRequest(settings)) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700454 HAL_LOGE("Invalid request settings.");
455 return false;
456 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700457 return true;
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700458}
459
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700460} // namespace v4l2_camera_hal