blob: f877895ebbe1d04353cf028491ad546dbe9f76e4 [file] [log] [blame]
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CamDevSession@3.3-impl"
18#include <android/log.h>
19
20#include <set>
21#include <utils/Trace.h>
22#include <hardware/gralloc.h>
23#include <hardware/gralloc1.h>
24#include "CameraDeviceSession.h"
25
26namespace android {
27namespace hardware {
28namespace camera {
29namespace device {
30namespace V3_3 {
31namespace implementation {
32
33CameraDeviceSession::CameraDeviceSession(
34 camera3_device_t* device,
35 const camera_metadata_t* deviceInfo,
36 const sp<V3_2::ICameraDeviceCallback>& callback) :
37 V3_2::implementation::CameraDeviceSession(device, deviceInfo, callback) {
38}
39
40CameraDeviceSession::~CameraDeviceSession() {
41}
42
43Return<void> CameraDeviceSession::configureStreams_3_3(
44 const StreamConfiguration& requestedConfiguration,
45 ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb) {
46 Status status = initStatus();
47 HalStreamConfiguration outStreams;
48
49 // hold the inflight lock for entire configureStreams scope since there must not be any
50 // inflight request/results during stream configuration.
51 Mutex::Autolock _l(mInflightLock);
52 if (!mInflightBuffers.empty()) {
53 ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
54 __FUNCTION__, mInflightBuffers.size());
55 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
56 return Void();
57 }
58
59 if (!mInflightAETriggerOverrides.empty()) {
60 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
61 " trigger overrides!", __FUNCTION__,
62 mInflightAETriggerOverrides.size());
63 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
64 return Void();
65 }
66
67 if (!mInflightRawBoostPresent.empty()) {
68 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
69 " boost overrides!", __FUNCTION__,
70 mInflightRawBoostPresent.size());
71 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
72 return Void();
73 }
74
75 if (status != Status::OK) {
76 _hidl_cb(status, outStreams);
77 return Void();
78 }
79
80 camera3_stream_configuration_t stream_list;
81 hidl_vec<camera3_stream_t*> streams;
82
83 stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode;
84 stream_list.num_streams = requestedConfiguration.streams.size();
85 streams.resize(stream_list.num_streams);
86 stream_list.streams = streams.data();
87
88 for (uint32_t i = 0; i < stream_list.num_streams; i++) {
89 int id = requestedConfiguration.streams[i].id;
90
91 if (mStreamMap.count(id) == 0) {
92 Camera3Stream stream;
93 V3_2::implementation::convertFromHidl(requestedConfiguration.streams[i], &stream);
94 mStreamMap[id] = stream;
95 mStreamMap[id].data_space = mapToLegacyDataspace(
96 mStreamMap[id].data_space);
97 mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
98 } else {
99 // width/height/format must not change, but usage/rotation might need to change
100 if (mStreamMap[id].stream_type !=
101 (int) requestedConfiguration.streams[i].streamType ||
102 mStreamMap[id].width != requestedConfiguration.streams[i].width ||
103 mStreamMap[id].height != requestedConfiguration.streams[i].height ||
104 mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
105 mStreamMap[id].data_space !=
106 mapToLegacyDataspace( static_cast<android_dataspace_t> (
107 requestedConfiguration.streams[i].dataSpace))) {
108 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
109 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
110 return Void();
111 }
112 mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
113 mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
114 }
115 streams[i] = &mStreamMap[id];
116 }
117
118 ATRACE_BEGIN("camera3->configure_streams");
119 status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
120 ATRACE_END();
121
122 // In case Hal returns error most likely it was not able to release
123 // the corresponding resources of the deleted streams.
124 if (ret == OK) {
125 // delete unused streams, note we do this after adding new streams to ensure new stream
126 // will not have the same address as deleted stream, and HAL has a chance to reference
127 // the to be deleted stream in configure_streams call
128 for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
129 int id = it->first;
130 bool found = false;
131 for (const auto& stream : requestedConfiguration.streams) {
132 if (id == stream.id) {
133 found = true;
134 break;
135 }
136 }
137 if (!found) {
138 // Unmap all buffers of deleted stream
139 // in case the configuration call succeeds and HAL
140 // is able to release the corresponding resources too.
141 cleanupBuffersLocked(id);
142 it = mStreamMap.erase(it);
143 } else {
144 ++it;
145 }
146 }
147
148 // Track video streams
149 mVideoStreamIds.clear();
150 for (const auto& stream : requestedConfiguration.streams) {
151 if (stream.streamType == V3_2::StreamType::OUTPUT &&
152 stream.usage &
153 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
154 mVideoStreamIds.push_back(stream.id);
155 }
156 }
157 mResultBatcher.setBatchedStreams(mVideoStreamIds);
158 }
159
160 if (ret == -EINVAL) {
161 status = Status::ILLEGAL_ARGUMENT;
162 } else if (ret != OK) {
163 status = Status::INTERNAL_ERROR;
164 } else {
165 convertToHidl(stream_list, &outStreams);
166 mFirstRequest = true;
167 }
168
169 _hidl_cb(status, outStreams);
170 return Void();
171}
172
173} // namespace implementation
174} // namespace V3_3
175} // namespace device
176} // namespace camera
177} // namespace hardware
178} // namespace android