1*e01b6f76SAndroid Build Coastguard Worker /*
2*e01b6f76SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*e01b6f76SAndroid Build Coastguard Worker *
4*e01b6f76SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e01b6f76SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e01b6f76SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e01b6f76SAndroid Build Coastguard Worker *
8*e01b6f76SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e01b6f76SAndroid Build Coastguard Worker *
10*e01b6f76SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e01b6f76SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e01b6f76SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e01b6f76SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e01b6f76SAndroid Build Coastguard Worker * limitations under the License.
15*e01b6f76SAndroid Build Coastguard Worker */
16*e01b6f76SAndroid Build Coastguard Worker
17*e01b6f76SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*e01b6f76SAndroid Build Coastguard Worker #define LOG_TAG "Camera"
19*e01b6f76SAndroid Build Coastguard Worker
20*e01b6f76SAndroid Build Coastguard Worker #include <errno.h>
21*e01b6f76SAndroid Build Coastguard Worker #include <stdio.h>
22*e01b6f76SAndroid Build Coastguard Worker #include <string.h>
23*e01b6f76SAndroid Build Coastguard Worker #include <time.h>
24*e01b6f76SAndroid Build Coastguard Worker
25*e01b6f76SAndroid Build Coastguard Worker #include <cstdlib>
26*e01b6f76SAndroid Build Coastguard Worker
27*e01b6f76SAndroid Build Coastguard Worker #include <log/log.h>
28*e01b6f76SAndroid Build Coastguard Worker #include <utils/Mutex.h>
29*e01b6f76SAndroid Build Coastguard Worker
30*e01b6f76SAndroid Build Coastguard Worker #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
31*e01b6f76SAndroid Build Coastguard Worker #include <utils/Trace.h>
32*e01b6f76SAndroid Build Coastguard Worker
33*e01b6f76SAndroid Build Coastguard Worker #include <hardware/camera3.h>
34*e01b6f76SAndroid Build Coastguard Worker #include <system/camera_metadata.h>
35*e01b6f76SAndroid Build Coastguard Worker #include <system/graphics.h>
36*e01b6f76SAndroid Build Coastguard Worker
37*e01b6f76SAndroid Build Coastguard Worker #include "CameraHAL.h"
38*e01b6f76SAndroid Build Coastguard Worker #include "Metadata.h"
39*e01b6f76SAndroid Build Coastguard Worker #include "Stream.h"
40*e01b6f76SAndroid Build Coastguard Worker
41*e01b6f76SAndroid Build Coastguard Worker #include "Camera.h"
42*e01b6f76SAndroid Build Coastguard Worker
43*e01b6f76SAndroid Build Coastguard Worker namespace usb_camera_hal {
44*e01b6f76SAndroid Build Coastguard Worker
45*e01b6f76SAndroid Build Coastguard Worker extern "C" {
46*e01b6f76SAndroid Build Coastguard Worker // Shim passed to the framework to close an opened device.
close_device(hw_device_t * dev)47*e01b6f76SAndroid Build Coastguard Worker static int close_device(hw_device_t* dev) {
48*e01b6f76SAndroid Build Coastguard Worker camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
49*e01b6f76SAndroid Build Coastguard Worker Camera* cam = static_cast<Camera*>(cam_dev->priv);
50*e01b6f76SAndroid Build Coastguard Worker return cam->close();
51*e01b6f76SAndroid Build Coastguard Worker }
52*e01b6f76SAndroid Build Coastguard Worker
53*e01b6f76SAndroid Build Coastguard Worker // Get handle to camera from device priv data
camdev_to_camera(const camera3_device_t * dev)54*e01b6f76SAndroid Build Coastguard Worker static Camera *camdev_to_camera(const camera3_device_t *dev) {
55*e01b6f76SAndroid Build Coastguard Worker return reinterpret_cast<Camera*>(dev->priv);
56*e01b6f76SAndroid Build Coastguard Worker }
57*e01b6f76SAndroid Build Coastguard Worker
initialize(const camera3_device_t * dev,const camera3_callback_ops_t * callback_ops)58*e01b6f76SAndroid Build Coastguard Worker static int initialize(const camera3_device_t *dev,
59*e01b6f76SAndroid Build Coastguard Worker const camera3_callback_ops_t *callback_ops) {
60*e01b6f76SAndroid Build Coastguard Worker return camdev_to_camera(dev)->initialize(callback_ops);
61*e01b6f76SAndroid Build Coastguard Worker }
62*e01b6f76SAndroid Build Coastguard Worker
configure_streams(const camera3_device_t * dev,camera3_stream_configuration_t * stream_list)63*e01b6f76SAndroid Build Coastguard Worker static int configure_streams(const camera3_device_t *dev,
64*e01b6f76SAndroid Build Coastguard Worker camera3_stream_configuration_t *stream_list) {
65*e01b6f76SAndroid Build Coastguard Worker return camdev_to_camera(dev)->configureStreams(stream_list);
66*e01b6f76SAndroid Build Coastguard Worker }
67*e01b6f76SAndroid Build Coastguard Worker
construct_default_request_settings(const camera3_device_t * dev,int type)68*e01b6f76SAndroid Build Coastguard Worker static const camera_metadata_t *construct_default_request_settings(
69*e01b6f76SAndroid Build Coastguard Worker const camera3_device_t *dev, int type) {
70*e01b6f76SAndroid Build Coastguard Worker return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
71*e01b6f76SAndroid Build Coastguard Worker }
72*e01b6f76SAndroid Build Coastguard Worker
process_capture_request(const camera3_device_t * dev,camera3_capture_request_t * request)73*e01b6f76SAndroid Build Coastguard Worker static int process_capture_request(const camera3_device_t *dev,
74*e01b6f76SAndroid Build Coastguard Worker camera3_capture_request_t *request) {
75*e01b6f76SAndroid Build Coastguard Worker return camdev_to_camera(dev)->processCaptureRequest(request);
76*e01b6f76SAndroid Build Coastguard Worker }
77*e01b6f76SAndroid Build Coastguard Worker
dump(const camera3_device_t * dev,int fd)78*e01b6f76SAndroid Build Coastguard Worker static void dump(const camera3_device_t *dev, int fd) {
79*e01b6f76SAndroid Build Coastguard Worker camdev_to_camera(dev)->dump(fd);
80*e01b6f76SAndroid Build Coastguard Worker }
81*e01b6f76SAndroid Build Coastguard Worker
flush(const camera3_device_t * dev)82*e01b6f76SAndroid Build Coastguard Worker static int flush(const camera3_device_t *dev) {
83*e01b6f76SAndroid Build Coastguard Worker return camdev_to_camera(dev)->flush();
84*e01b6f76SAndroid Build Coastguard Worker }
85*e01b6f76SAndroid Build Coastguard Worker
86*e01b6f76SAndroid Build Coastguard Worker } // extern "C"
87*e01b6f76SAndroid Build Coastguard Worker
88*e01b6f76SAndroid Build Coastguard Worker const camera3_device_ops_t Camera::sOps = {
89*e01b6f76SAndroid Build Coastguard Worker .initialize = usb_camera_hal::initialize,
90*e01b6f76SAndroid Build Coastguard Worker .configure_streams = usb_camera_hal::configure_streams,
91*e01b6f76SAndroid Build Coastguard Worker .register_stream_buffers = NULL,
92*e01b6f76SAndroid Build Coastguard Worker .construct_default_request_settings
93*e01b6f76SAndroid Build Coastguard Worker = usb_camera_hal::construct_default_request_settings,
94*e01b6f76SAndroid Build Coastguard Worker .process_capture_request = usb_camera_hal::process_capture_request,
95*e01b6f76SAndroid Build Coastguard Worker .get_metadata_vendor_tag_ops = NULL,
96*e01b6f76SAndroid Build Coastguard Worker .dump = usb_camera_hal::dump,
97*e01b6f76SAndroid Build Coastguard Worker .flush = usb_camera_hal::flush,
98*e01b6f76SAndroid Build Coastguard Worker .reserved = {0},
99*e01b6f76SAndroid Build Coastguard Worker };
100*e01b6f76SAndroid Build Coastguard Worker
Camera(int id)101*e01b6f76SAndroid Build Coastguard Worker Camera::Camera(int id)
102*e01b6f76SAndroid Build Coastguard Worker : mId(id),
103*e01b6f76SAndroid Build Coastguard Worker mStaticInfo(NULL),
104*e01b6f76SAndroid Build Coastguard Worker mBusy(false),
105*e01b6f76SAndroid Build Coastguard Worker mCallbackOps(NULL),
106*e01b6f76SAndroid Build Coastguard Worker mSettings(NULL),
107*e01b6f76SAndroid Build Coastguard Worker mIsInitialized(false) {
108*e01b6f76SAndroid Build Coastguard Worker memset(&mTemplates, 0, sizeof(mTemplates));
109*e01b6f76SAndroid Build Coastguard Worker memset(&mDevice, 0, sizeof(mDevice));
110*e01b6f76SAndroid Build Coastguard Worker mDevice.common.tag = HARDWARE_DEVICE_TAG;
111*e01b6f76SAndroid Build Coastguard Worker // TODO: Upgrade to HAL3.3
112*e01b6f76SAndroid Build Coastguard Worker mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_2;
113*e01b6f76SAndroid Build Coastguard Worker mDevice.common.close = close_device;
114*e01b6f76SAndroid Build Coastguard Worker mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
115*e01b6f76SAndroid Build Coastguard Worker mDevice.priv = this;
116*e01b6f76SAndroid Build Coastguard Worker }
117*e01b6f76SAndroid Build Coastguard Worker
~Camera()118*e01b6f76SAndroid Build Coastguard Worker Camera::~Camera() {
119*e01b6f76SAndroid Build Coastguard Worker if (mStaticInfo != NULL) {
120*e01b6f76SAndroid Build Coastguard Worker free_camera_metadata(mStaticInfo);
121*e01b6f76SAndroid Build Coastguard Worker }
122*e01b6f76SAndroid Build Coastguard Worker
123*e01b6f76SAndroid Build Coastguard Worker for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
124*e01b6f76SAndroid Build Coastguard Worker free_camera_metadata(mTemplates[i]);
125*e01b6f76SAndroid Build Coastguard Worker }
126*e01b6f76SAndroid Build Coastguard Worker
127*e01b6f76SAndroid Build Coastguard Worker if (mSettings != NULL) {
128*e01b6f76SAndroid Build Coastguard Worker free_camera_metadata(mSettings);
129*e01b6f76SAndroid Build Coastguard Worker }
130*e01b6f76SAndroid Build Coastguard Worker }
131*e01b6f76SAndroid Build Coastguard Worker
open(const hw_module_t * module,hw_device_t ** device)132*e01b6f76SAndroid Build Coastguard Worker int Camera::open(const hw_module_t *module, hw_device_t **device) {
133*e01b6f76SAndroid Build Coastguard Worker ALOGI("%s:%d: Opening camera device", __func__, mId);
134*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
135*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
136*e01b6f76SAndroid Build Coastguard Worker
137*e01b6f76SAndroid Build Coastguard Worker if (mBusy) {
138*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
139*e01b6f76SAndroid Build Coastguard Worker return -EBUSY;
140*e01b6f76SAndroid Build Coastguard Worker }
141*e01b6f76SAndroid Build Coastguard Worker
142*e01b6f76SAndroid Build Coastguard Worker mBusy = true;
143*e01b6f76SAndroid Build Coastguard Worker mDevice.common.module = const_cast<hw_module_t*>(module);
144*e01b6f76SAndroid Build Coastguard Worker *device = &mDevice.common;
145*e01b6f76SAndroid Build Coastguard Worker return openDevice();
146*e01b6f76SAndroid Build Coastguard Worker }
147*e01b6f76SAndroid Build Coastguard Worker
getInfo(struct camera_info * info)148*e01b6f76SAndroid Build Coastguard Worker int Camera::getInfo(struct camera_info *info) {
149*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mStaticInfoLock);
150*e01b6f76SAndroid Build Coastguard Worker
151*e01b6f76SAndroid Build Coastguard Worker // TODO: update to CAMERA_FACING_EXTERNAL once the HAL API changes are merged.
152*e01b6f76SAndroid Build Coastguard Worker info->facing = CAMERA_FACING_FRONT;
153*e01b6f76SAndroid Build Coastguard Worker info->orientation = 0;
154*e01b6f76SAndroid Build Coastguard Worker info->device_version = mDevice.common.version;
155*e01b6f76SAndroid Build Coastguard Worker if (mStaticInfo == NULL) {
156*e01b6f76SAndroid Build Coastguard Worker initStaticInfo();
157*e01b6f76SAndroid Build Coastguard Worker }
158*e01b6f76SAndroid Build Coastguard Worker info->static_camera_characteristics = mStaticInfo;
159*e01b6f76SAndroid Build Coastguard Worker return 0;
160*e01b6f76SAndroid Build Coastguard Worker }
161*e01b6f76SAndroid Build Coastguard Worker
updateInfo()162*e01b6f76SAndroid Build Coastguard Worker void Camera::updateInfo() {
163*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mStaticInfoLock);
164*e01b6f76SAndroid Build Coastguard Worker initStaticInfo();
165*e01b6f76SAndroid Build Coastguard Worker }
166*e01b6f76SAndroid Build Coastguard Worker
close()167*e01b6f76SAndroid Build Coastguard Worker int Camera::close() {
168*e01b6f76SAndroid Build Coastguard Worker ALOGI("%s:%d: Closing camera device", __func__, mId);
169*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
170*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
171*e01b6f76SAndroid Build Coastguard Worker
172*e01b6f76SAndroid Build Coastguard Worker if (!mBusy) {
173*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
174*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
175*e01b6f76SAndroid Build Coastguard Worker }
176*e01b6f76SAndroid Build Coastguard Worker
177*e01b6f76SAndroid Build Coastguard Worker mBusy = false;
178*e01b6f76SAndroid Build Coastguard Worker mIsInitialized = false;
179*e01b6f76SAndroid Build Coastguard Worker return closeDevice();
180*e01b6f76SAndroid Build Coastguard Worker }
181*e01b6f76SAndroid Build Coastguard Worker
initialize(const camera3_callback_ops_t * callback_ops)182*e01b6f76SAndroid Build Coastguard Worker int Camera::initialize(const camera3_callback_ops_t *callback_ops) {
183*e01b6f76SAndroid Build Coastguard Worker int res;
184*e01b6f76SAndroid Build Coastguard Worker
185*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
186*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
187*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
188*e01b6f76SAndroid Build Coastguard Worker
189*e01b6f76SAndroid Build Coastguard Worker mCallbackOps = callback_ops;
190*e01b6f76SAndroid Build Coastguard Worker // per-device specific initialization
191*e01b6f76SAndroid Build Coastguard Worker res = initDevice();
192*e01b6f76SAndroid Build Coastguard Worker if (res != 0) {
193*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
194*e01b6f76SAndroid Build Coastguard Worker return res;
195*e01b6f76SAndroid Build Coastguard Worker }
196*e01b6f76SAndroid Build Coastguard Worker
197*e01b6f76SAndroid Build Coastguard Worker mIsInitialized = true;
198*e01b6f76SAndroid Build Coastguard Worker return 0;
199*e01b6f76SAndroid Build Coastguard Worker }
200*e01b6f76SAndroid Build Coastguard Worker
configureStreams(camera3_stream_configuration_t * stream_config)201*e01b6f76SAndroid Build Coastguard Worker int Camera::configureStreams(camera3_stream_configuration_t *stream_config) {
202*e01b6f76SAndroid Build Coastguard Worker camera3_stream_t *astream;
203*e01b6f76SAndroid Build Coastguard Worker android::Vector<Stream *> newStreams;
204*e01b6f76SAndroid Build Coastguard Worker
205*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
206*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
207*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
208*e01b6f76SAndroid Build Coastguard Worker if (!mIsInitialized) {
209*e01b6f76SAndroid Build Coastguard Worker ALOGE("Device is not initialized yet");
210*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
211*e01b6f76SAndroid Build Coastguard Worker }
212*e01b6f76SAndroid Build Coastguard Worker
213*e01b6f76SAndroid Build Coastguard Worker if (stream_config == NULL) {
214*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
215*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
216*e01b6f76SAndroid Build Coastguard Worker }
217*e01b6f76SAndroid Build Coastguard Worker if (stream_config->num_streams == 0) {
218*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
219*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
220*e01b6f76SAndroid Build Coastguard Worker }
221*e01b6f76SAndroid Build Coastguard Worker
222*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
223*e01b6f76SAndroid Build Coastguard Worker stream_config->num_streams);
224*e01b6f76SAndroid Build Coastguard Worker // Mark all current streams unused for now
225*e01b6f76SAndroid Build Coastguard Worker for (size_t i = 0; i < mStreams.size(); i++) {
226*e01b6f76SAndroid Build Coastguard Worker mStreams[i]->mReuse = false;
227*e01b6f76SAndroid Build Coastguard Worker }
228*e01b6f76SAndroid Build Coastguard Worker // Fill new stream array with reused streams and new streams
229*e01b6f76SAndroid Build Coastguard Worker for (unsigned int i = 0; i < stream_config->num_streams; i++) {
230*e01b6f76SAndroid Build Coastguard Worker astream = stream_config->streams[i];
231*e01b6f76SAndroid Build Coastguard Worker if (astream->max_buffers > 0) {
232*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
233*e01b6f76SAndroid Build Coastguard Worker newStreams.add(reuseStreamLocked(astream));
234*e01b6f76SAndroid Build Coastguard Worker } else {
235*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
236*e01b6f76SAndroid Build Coastguard Worker newStreams.add(new Stream(mId, astream));
237*e01b6f76SAndroid Build Coastguard Worker }
238*e01b6f76SAndroid Build Coastguard Worker
239*e01b6f76SAndroid Build Coastguard Worker if (newStreams[i] == NULL) {
240*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
241*e01b6f76SAndroid Build Coastguard Worker goto err_out;
242*e01b6f76SAndroid Build Coastguard Worker }
243*e01b6f76SAndroid Build Coastguard Worker astream->priv = reinterpret_cast<void *>(newStreams[i]);
244*e01b6f76SAndroid Build Coastguard Worker }
245*e01b6f76SAndroid Build Coastguard Worker
246*e01b6f76SAndroid Build Coastguard Worker // Verify the set of streams in aggregate
247*e01b6f76SAndroid Build Coastguard Worker if (!isValidStreamSetLocked(newStreams)) {
248*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Invalid stream set", __func__, mId);
249*e01b6f76SAndroid Build Coastguard Worker goto err_out;
250*e01b6f76SAndroid Build Coastguard Worker }
251*e01b6f76SAndroid Build Coastguard Worker
252*e01b6f76SAndroid Build Coastguard Worker // Set up all streams (calculate usage/max_buffers for each)
253*e01b6f76SAndroid Build Coastguard Worker setupStreamsLocked(newStreams);
254*e01b6f76SAndroid Build Coastguard Worker
255*e01b6f76SAndroid Build Coastguard Worker // Destroy all old streams and replace stream array with new one
256*e01b6f76SAndroid Build Coastguard Worker destroyStreamsLocked(mStreams);
257*e01b6f76SAndroid Build Coastguard Worker mStreams = newStreams;
258*e01b6f76SAndroid Build Coastguard Worker
259*e01b6f76SAndroid Build Coastguard Worker // Clear out last seen settings metadata
260*e01b6f76SAndroid Build Coastguard Worker updateSettingsLocked(NULL);
261*e01b6f76SAndroid Build Coastguard Worker return 0;
262*e01b6f76SAndroid Build Coastguard Worker
263*e01b6f76SAndroid Build Coastguard Worker err_out:
264*e01b6f76SAndroid Build Coastguard Worker // Clean up temporary streams, preserve existing mStreams
265*e01b6f76SAndroid Build Coastguard Worker destroyStreamsLocked(newStreams);
266*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
267*e01b6f76SAndroid Build Coastguard Worker }
268*e01b6f76SAndroid Build Coastguard Worker
destroyStreamsLocked(android::Vector<Stream * > & streams)269*e01b6f76SAndroid Build Coastguard Worker void Camera::destroyStreamsLocked(android::Vector<Stream *> &streams) {
270*e01b6f76SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); i++) {
271*e01b6f76SAndroid Build Coastguard Worker delete streams[i];
272*e01b6f76SAndroid Build Coastguard Worker }
273*e01b6f76SAndroid Build Coastguard Worker streams.clear();
274*e01b6f76SAndroid Build Coastguard Worker }
275*e01b6f76SAndroid Build Coastguard Worker
reuseStreamLocked(camera3_stream_t * astream)276*e01b6f76SAndroid Build Coastguard Worker Stream *Camera::reuseStreamLocked(camera3_stream_t *astream) {
277*e01b6f76SAndroid Build Coastguard Worker Stream *priv = reinterpret_cast<Stream*>(astream->priv);
278*e01b6f76SAndroid Build Coastguard Worker // Verify the re-used stream's parameters match
279*e01b6f76SAndroid Build Coastguard Worker if (!priv->isValidReuseStream(mId, astream)) {
280*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
281*e01b6f76SAndroid Build Coastguard Worker return NULL;
282*e01b6f76SAndroid Build Coastguard Worker }
283*e01b6f76SAndroid Build Coastguard Worker // Mark stream to be reused
284*e01b6f76SAndroid Build Coastguard Worker priv->mReuse = true;
285*e01b6f76SAndroid Build Coastguard Worker return priv;
286*e01b6f76SAndroid Build Coastguard Worker }
287*e01b6f76SAndroid Build Coastguard Worker
isValidStreamSetLocked(const android::Vector<Stream * > & streams)288*e01b6f76SAndroid Build Coastguard Worker bool Camera::isValidStreamSetLocked(const android::Vector<Stream *> &streams) {
289*e01b6f76SAndroid Build Coastguard Worker int inputs = 0;
290*e01b6f76SAndroid Build Coastguard Worker int outputs = 0;
291*e01b6f76SAndroid Build Coastguard Worker
292*e01b6f76SAndroid Build Coastguard Worker if (streams.isEmpty()) {
293*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
294*e01b6f76SAndroid Build Coastguard Worker return false;
295*e01b6f76SAndroid Build Coastguard Worker }
296*e01b6f76SAndroid Build Coastguard Worker // Validate there is at most one input stream and at least one output stream
297*e01b6f76SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); i++) {
298*e01b6f76SAndroid Build Coastguard Worker // A stream may be both input and output (bidirectional)
299*e01b6f76SAndroid Build Coastguard Worker if (streams[i]->isInputType())
300*e01b6f76SAndroid Build Coastguard Worker inputs++;
301*e01b6f76SAndroid Build Coastguard Worker if (streams[i]->isOutputType())
302*e01b6f76SAndroid Build Coastguard Worker outputs++;
303*e01b6f76SAndroid Build Coastguard Worker }
304*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Configuring %d output streams and %d input streams",
305*e01b6f76SAndroid Build Coastguard Worker __func__, mId, outputs, inputs);
306*e01b6f76SAndroid Build Coastguard Worker if (outputs < 1) {
307*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
308*e01b6f76SAndroid Build Coastguard Worker return false;
309*e01b6f76SAndroid Build Coastguard Worker }
310*e01b6f76SAndroid Build Coastguard Worker if (inputs > 1) {
311*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
312*e01b6f76SAndroid Build Coastguard Worker return false;
313*e01b6f76SAndroid Build Coastguard Worker }
314*e01b6f76SAndroid Build Coastguard Worker // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
315*e01b6f76SAndroid Build Coastguard Worker return true;
316*e01b6f76SAndroid Build Coastguard Worker }
317*e01b6f76SAndroid Build Coastguard Worker
setupStreamsLocked(android::Vector<Stream * > & streams)318*e01b6f76SAndroid Build Coastguard Worker void Camera::setupStreamsLocked(android::Vector<Stream *> &streams) {
319*e01b6f76SAndroid Build Coastguard Worker /*
320*e01b6f76SAndroid Build Coastguard Worker * This is where the HAL has to decide internally how to handle all of the
321*e01b6f76SAndroid Build Coastguard Worker * streams, and then produce usage and max_buffer values for each stream.
322*e01b6f76SAndroid Build Coastguard Worker * Note, the stream vector has been checked before this point for ALL invalid
323*e01b6f76SAndroid Build Coastguard Worker * conditions, so it must find a successful configuration for this stream
324*e01b6f76SAndroid Build Coastguard Worker * array. The HAL may not return an error from this point.
325*e01b6f76SAndroid Build Coastguard Worker *
326*e01b6f76SAndroid Build Coastguard Worker * TODO: we just set all streams to be the same dummy values;
327*e01b6f76SAndroid Build Coastguard Worker * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
328*e01b6f76SAndroid Build Coastguard Worker */
329*e01b6f76SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); i++) {
330*e01b6f76SAndroid Build Coastguard Worker uint32_t usage = 0;
331*e01b6f76SAndroid Build Coastguard Worker
332*e01b6f76SAndroid Build Coastguard Worker if (streams[i]->isOutputType())
333*e01b6f76SAndroid Build Coastguard Worker usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
334*e01b6f76SAndroid Build Coastguard Worker GRALLOC_USAGE_HW_CAMERA_WRITE;
335*e01b6f76SAndroid Build Coastguard Worker if (streams[i]->isInputType())
336*e01b6f76SAndroid Build Coastguard Worker usage |= GRALLOC_USAGE_SW_READ_OFTEN |
337*e01b6f76SAndroid Build Coastguard Worker GRALLOC_USAGE_HW_CAMERA_READ;
338*e01b6f76SAndroid Build Coastguard Worker
339*e01b6f76SAndroid Build Coastguard Worker streams[i]->setUsage(usage);
340*e01b6f76SAndroid Build Coastguard Worker streams[i]->setMaxBuffers(1);
341*e01b6f76SAndroid Build Coastguard Worker }
342*e01b6f76SAndroid Build Coastguard Worker }
343*e01b6f76SAndroid Build Coastguard Worker
isValidTemplateType(int type)344*e01b6f76SAndroid Build Coastguard Worker bool Camera::isValidTemplateType(int type) {
345*e01b6f76SAndroid Build Coastguard Worker return type >= 1 && type < CAMERA3_TEMPLATE_COUNT;
346*e01b6f76SAndroid Build Coastguard Worker }
347*e01b6f76SAndroid Build Coastguard Worker
constructDefaultRequestSettings(int type)348*e01b6f76SAndroid Build Coastguard Worker const camera_metadata_t* Camera::constructDefaultRequestSettings(int type) {
349*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: type=%d", __func__, mId, type);
350*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
351*e01b6f76SAndroid Build Coastguard Worker
352*e01b6f76SAndroid Build Coastguard Worker if (!isValidTemplateType(type)) {
353*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
354*e01b6f76SAndroid Build Coastguard Worker return NULL;
355*e01b6f76SAndroid Build Coastguard Worker }
356*e01b6f76SAndroid Build Coastguard Worker
357*e01b6f76SAndroid Build Coastguard Worker // DO NOT try to initialize the device here, it will be guaranteed deadlock.
358*e01b6f76SAndroid Build Coastguard Worker if (!mIsInitialized) {
359*e01b6f76SAndroid Build Coastguard Worker ALOGE("Device is not initialized yet");
360*e01b6f76SAndroid Build Coastguard Worker return NULL;
361*e01b6f76SAndroid Build Coastguard Worker }
362*e01b6f76SAndroid Build Coastguard Worker
363*e01b6f76SAndroid Build Coastguard Worker return mTemplates[type];
364*e01b6f76SAndroid Build Coastguard Worker }
365*e01b6f76SAndroid Build Coastguard Worker
366*e01b6f76SAndroid Build Coastguard Worker // This implementation is a copy-paste, probably we should override (or move) this to
367*e01b6f76SAndroid Build Coastguard Worker // device specific class.
processCaptureRequest(camera3_capture_request_t * request)368*e01b6f76SAndroid Build Coastguard Worker int Camera::processCaptureRequest(camera3_capture_request_t *request) {
369*e01b6f76SAndroid Build Coastguard Worker camera3_capture_result result;
370*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: request=%p", __func__, mId, request);
371*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
372*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
373*e01b6f76SAndroid Build Coastguard Worker
374*e01b6f76SAndroid Build Coastguard Worker if (request == NULL) {
375*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: NULL request recieved", __func__, mId);
376*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
377*e01b6f76SAndroid Build Coastguard Worker }
378*e01b6f76SAndroid Build Coastguard Worker
379*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
380*e01b6f76SAndroid Build Coastguard Worker request->frame_number, request->settings);
381*e01b6f76SAndroid Build Coastguard Worker
382*e01b6f76SAndroid Build Coastguard Worker // NULL indicates use last settings
383*e01b6f76SAndroid Build Coastguard Worker if (request->settings == NULL) {
384*e01b6f76SAndroid Build Coastguard Worker if (mSettings == NULL) {
385*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
386*e01b6f76SAndroid Build Coastguard Worker __func__, mId, request->frame_number, request);
387*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
388*e01b6f76SAndroid Build Coastguard Worker }
389*e01b6f76SAndroid Build Coastguard Worker } else {
390*e01b6f76SAndroid Build Coastguard Worker updateSettingsLocked(request->settings);
391*e01b6f76SAndroid Build Coastguard Worker }
392*e01b6f76SAndroid Build Coastguard Worker
393*e01b6f76SAndroid Build Coastguard Worker if (request->input_buffer != NULL) {
394*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Reprocessing input buffer is not supported yet", __func__, mId);
395*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
396*e01b6f76SAndroid Build Coastguard Worker } else {
397*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Capturing new frame.", __func__, mId);
398*e01b6f76SAndroid Build Coastguard Worker
399*e01b6f76SAndroid Build Coastguard Worker if (!isValidCaptureSettings(request->settings)) {
400*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Invalid settings for capture request: %p",
401*e01b6f76SAndroid Build Coastguard Worker __func__, mId, request->settings);
402*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
403*e01b6f76SAndroid Build Coastguard Worker }
404*e01b6f76SAndroid Build Coastguard Worker }
405*e01b6f76SAndroid Build Coastguard Worker
406*e01b6f76SAndroid Build Coastguard Worker if (request->num_output_buffers <= 0) {
407*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
408*e01b6f76SAndroid Build Coastguard Worker request->num_output_buffers);
409*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
410*e01b6f76SAndroid Build Coastguard Worker }
411*e01b6f76SAndroid Build Coastguard Worker result.num_output_buffers = request->num_output_buffers;
412*e01b6f76SAndroid Build Coastguard Worker result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers];
413*e01b6f76SAndroid Build Coastguard Worker for (unsigned int i = 0; i < request->num_output_buffers; i++) {
414*e01b6f76SAndroid Build Coastguard Worker int res = processCaptureBuffer(&request->output_buffers[i],
415*e01b6f76SAndroid Build Coastguard Worker const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i]));
416*e01b6f76SAndroid Build Coastguard Worker if (res) {
417*e01b6f76SAndroid Build Coastguard Worker delete [] result.output_buffers;
418*e01b6f76SAndroid Build Coastguard Worker // TODO: this should probably be a total device failure; transient for now
419*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
420*e01b6f76SAndroid Build Coastguard Worker }
421*e01b6f76SAndroid Build Coastguard Worker }
422*e01b6f76SAndroid Build Coastguard Worker
423*e01b6f76SAndroid Build Coastguard Worker result.frame_number = request->frame_number;
424*e01b6f76SAndroid Build Coastguard Worker // TODO: return actual captured/reprocessed settings
425*e01b6f76SAndroid Build Coastguard Worker result.result = request->settings;
426*e01b6f76SAndroid Build Coastguard Worker // TODO: asynchronously return results
427*e01b6f76SAndroid Build Coastguard Worker notifyShutter(request->frame_number, 0);
428*e01b6f76SAndroid Build Coastguard Worker mCallbackOps->process_capture_result(mCallbackOps, &result);
429*e01b6f76SAndroid Build Coastguard Worker
430*e01b6f76SAndroid Build Coastguard Worker // Free up capture result related resources, HAL owns the capture result, and it
431*e01b6f76SAndroid Build Coastguard Worker // is only valid during the process_capture_result call.
432*e01b6f76SAndroid Build Coastguard Worker delete[] result.output_buffers;
433*e01b6f76SAndroid Build Coastguard Worker
434*e01b6f76SAndroid Build Coastguard Worker return 0;
435*e01b6f76SAndroid Build Coastguard Worker }
436*e01b6f76SAndroid Build Coastguard Worker
flush()437*e01b6f76SAndroid Build Coastguard Worker int Camera::flush() {
438*e01b6f76SAndroid Build Coastguard Worker int res;
439*e01b6f76SAndroid Build Coastguard Worker
440*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: flush device", __func__, mId);
441*e01b6f76SAndroid Build Coastguard Worker // per-device specific flush
442*e01b6f76SAndroid Build Coastguard Worker res = flushDevice();
443*e01b6f76SAndroid Build Coastguard Worker if (res != 0) {
444*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Failed to flush device!", __func__, mId);
445*e01b6f76SAndroid Build Coastguard Worker return res;
446*e01b6f76SAndroid Build Coastguard Worker }
447*e01b6f76SAndroid Build Coastguard Worker return 0;
448*e01b6f76SAndroid Build Coastguard Worker }
449*e01b6f76SAndroid Build Coastguard Worker
updateSettingsLocked(const camera_metadata_t * new_settings)450*e01b6f76SAndroid Build Coastguard Worker void Camera::updateSettingsLocked(const camera_metadata_t *new_settings) {
451*e01b6f76SAndroid Build Coastguard Worker if (mSettings != NULL) {
452*e01b6f76SAndroid Build Coastguard Worker free_camera_metadata(mSettings);
453*e01b6f76SAndroid Build Coastguard Worker mSettings = NULL;
454*e01b6f76SAndroid Build Coastguard Worker }
455*e01b6f76SAndroid Build Coastguard Worker
456*e01b6f76SAndroid Build Coastguard Worker if (new_settings != NULL)
457*e01b6f76SAndroid Build Coastguard Worker mSettings = clone_camera_metadata(new_settings);
458*e01b6f76SAndroid Build Coastguard Worker }
459*e01b6f76SAndroid Build Coastguard Worker
notifyShutter(uint32_t frame_number,uint64_t timestamp)460*e01b6f76SAndroid Build Coastguard Worker void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp) {
461*e01b6f76SAndroid Build Coastguard Worker int res;
462*e01b6f76SAndroid Build Coastguard Worker struct timespec ts;
463*e01b6f76SAndroid Build Coastguard Worker
464*e01b6f76SAndroid Build Coastguard Worker // If timestamp is 0, get timestamp from right now instead
465*e01b6f76SAndroid Build Coastguard Worker if (timestamp == 0) {
466*e01b6f76SAndroid Build Coastguard Worker ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
467*e01b6f76SAndroid Build Coastguard Worker __func__, mId);
468*e01b6f76SAndroid Build Coastguard Worker res = clock_gettime(CLOCK_BOOTTIME, &ts);
469*e01b6f76SAndroid Build Coastguard Worker if (res == 0) {
470*e01b6f76SAndroid Build Coastguard Worker timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
471*e01b6f76SAndroid Build Coastguard Worker } else {
472*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
473*e01b6f76SAndroid Build Coastguard Worker __func__, mId, strerror(errno), errno);
474*e01b6f76SAndroid Build Coastguard Worker }
475*e01b6f76SAndroid Build Coastguard Worker }
476*e01b6f76SAndroid Build Coastguard Worker camera3_notify_msg_t m;
477*e01b6f76SAndroid Build Coastguard Worker memset(&m, 0, sizeof(m));
478*e01b6f76SAndroid Build Coastguard Worker m.type = CAMERA3_MSG_SHUTTER;
479*e01b6f76SAndroid Build Coastguard Worker m.message.shutter.frame_number = frame_number;
480*e01b6f76SAndroid Build Coastguard Worker m.message.shutter.timestamp = timestamp;
481*e01b6f76SAndroid Build Coastguard Worker mCallbackOps->notify(mCallbackOps, &m);
482*e01b6f76SAndroid Build Coastguard Worker }
483*e01b6f76SAndroid Build Coastguard Worker
dump(int fd)484*e01b6f76SAndroid Build Coastguard Worker void Camera::dump(int fd) {
485*e01b6f76SAndroid Build Coastguard Worker ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
486*e01b6f76SAndroid Build Coastguard Worker ATRACE_CALL();
487*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
488*e01b6f76SAndroid Build Coastguard Worker
489*e01b6f76SAndroid Build Coastguard Worker dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
490*e01b6f76SAndroid Build Coastguard Worker
491*e01b6f76SAndroid Build Coastguard Worker // TODO: dump all settings
492*e01b6f76SAndroid Build Coastguard Worker dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
493*e01b6f76SAndroid Build Coastguard Worker
494*e01b6f76SAndroid Build Coastguard Worker dprintf(fd, "Number of streams: %zu\n", mStreams.size());
495*e01b6f76SAndroid Build Coastguard Worker for (size_t i = 0; i < mStreams.size(); i++) {
496*e01b6f76SAndroid Build Coastguard Worker dprintf(fd, "Stream %zu/%zu:\n", i, mStreams.size());
497*e01b6f76SAndroid Build Coastguard Worker mStreams[i]->dump(fd);
498*e01b6f76SAndroid Build Coastguard Worker }
499*e01b6f76SAndroid Build Coastguard Worker }
500*e01b6f76SAndroid Build Coastguard Worker
templateToString(int type)501*e01b6f76SAndroid Build Coastguard Worker const char* Camera::templateToString(int type) {
502*e01b6f76SAndroid Build Coastguard Worker switch (type) {
503*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_PREVIEW:
504*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_PREVIEW";
505*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_STILL_CAPTURE:
506*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_STILL_CAPTURE";
507*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_VIDEO_RECORD:
508*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_VIDEO_RECORD";
509*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
510*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
511*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
512*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
513*e01b6f76SAndroid Build Coastguard Worker case CAMERA3_TEMPLATE_MANUAL:
514*e01b6f76SAndroid Build Coastguard Worker return "CAMERA3_TEMPLATE_MANUAL";
515*e01b6f76SAndroid Build Coastguard Worker }
516*e01b6f76SAndroid Build Coastguard Worker
517*e01b6f76SAndroid Build Coastguard Worker return "Invalid template type!";
518*e01b6f76SAndroid Build Coastguard Worker }
519*e01b6f76SAndroid Build Coastguard Worker
setTemplate(int type,camera_metadata_t * settings)520*e01b6f76SAndroid Build Coastguard Worker int Camera::setTemplate(int type, camera_metadata_t *settings) {
521*e01b6f76SAndroid Build Coastguard Worker android::Mutex::Autolock al(mDeviceLock);
522*e01b6f76SAndroid Build Coastguard Worker
523*e01b6f76SAndroid Build Coastguard Worker if (!isValidTemplateType(type)) {
524*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
525*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
526*e01b6f76SAndroid Build Coastguard Worker }
527*e01b6f76SAndroid Build Coastguard Worker
528*e01b6f76SAndroid Build Coastguard Worker if (mTemplates[type] != NULL) {
529*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Setting already constructed template type %s(%d)",
530*e01b6f76SAndroid Build Coastguard Worker __func__, mId, templateToString(type), type);
531*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
532*e01b6f76SAndroid Build Coastguard Worker }
533*e01b6f76SAndroid Build Coastguard Worker
534*e01b6f76SAndroid Build Coastguard Worker // Make a durable copy of the underlying metadata
535*e01b6f76SAndroid Build Coastguard Worker mTemplates[type] = clone_camera_metadata(settings);
536*e01b6f76SAndroid Build Coastguard Worker if (mTemplates[type] == NULL) {
537*e01b6f76SAndroid Build Coastguard Worker ALOGE("%s:%d: Failed to clone metadata %p for template type %s(%d)",
538*e01b6f76SAndroid Build Coastguard Worker __func__, mId, settings, templateToString(type), type);
539*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
540*e01b6f76SAndroid Build Coastguard Worker }
541*e01b6f76SAndroid Build Coastguard Worker return 0;
542*e01b6f76SAndroid Build Coastguard Worker }
543*e01b6f76SAndroid Build Coastguard Worker
544*e01b6f76SAndroid Build Coastguard Worker } // namespace usb_camera_hal
545