blob: 4b0cfc4004e8de7534eb1f343adc1dfd55fb92d3 [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 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 "Camera2Device"
18//#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
21#include "Camera2Device.h"
22
23namespace android {
24
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070025Camera2Device::Camera2Device(int id):
26 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070027 mDevice(NULL)
28{
29
30}
31
32Camera2Device::~Camera2Device()
33{
34 if (mDevice) {
35 status_t res;
36 res = mDevice->common.close(&mDevice->common);
37 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070038 ALOGE("%s: Could not close camera %d: %s (%d)",
39 __FUNCTION__,
40 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070041 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070042 mDevice = NULL;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070043 }
44}
45
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070046status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070047{
48 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070049 char name[10];
50 snprintf(name, sizeof(name), "%d", mId);
51
52 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070053 reinterpret_cast<hw_device_t**>(&mDevice));
54
55 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070056 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
57 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070058 return res;
59 }
60
61 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062 ALOGE("%s: Could not open camera %d: "
63 "Camera device is not version %x, reports %x instead",
64 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
65 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070066 return BAD_VALUE;
67 }
68
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070069 camera_info info;
70 res = module->get_camera_info(mId, &info);
71 if (res != OK ) return res;
72
73 if (info.device_version != mDevice->common.version) {
74 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
75 " and device version (%x).", __FUNCTION__,
76 mDevice->common.version, info.device_version);
77 return BAD_VALUE;
78 }
79
80 mDeviceInfo = info.static_camera_characteristics;
81
82 res = mDevice->ops->set_request_queue_src_ops(mDevice,
83 mRequestQueue.getToConsumerInterface());
84 if (res != OK) return res;
85
86 res = mDevice->ops->set_frame_queue_dst_ops(mDevice,
87 mFrameQueue.getToProducerInterface());
88 if (res != OK) return res;
89
90 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
91 if (res != OK ) return res;
92
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070093 return OK;
94}
95
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070096status_t Camera2Device::setStreamingRequest(camera_metadata_t* request)
97{
98 mRequestQueue.setStreamSlot(request);
99 return OK;
100}
101
102/**
103 * Camera2Device::MetadataQueue
104 */
105
106Camera2Device::MetadataQueue::MetadataQueue():
107 mDevice(NULL),
108 mFrameCount(0),
109 mCount(0),
110 mStreamSlotCount(0),
111 mSignalConsumer(true)
112{
113 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
114 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
115 camera2_request_queue_src_ops::free_request = consumer_free;
116
117 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
118 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
119 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
120}
121
122Camera2Device::MetadataQueue::~MetadataQueue() {
123 Mutex::Autolock l(mMutex);
124 freeBuffers(mEntries.begin(), mEntries.end());
125 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
126}
127
128// Interface to camera2 HAL as consumer (input requests/reprocessing)
129const camera2_request_queue_src_ops_t*
130Camera2Device::MetadataQueue::getToConsumerInterface() {
131 return static_cast<camera2_request_queue_src_ops_t*>(this);
132}
133
134void Camera2Device::MetadataQueue::setFromConsumerInterface(camera2_device_t *d) {
135 Mutex::Autolock l(mMutex);
136 mDevice = d;
137}
138
139const camera2_frame_queue_dst_ops_t*
140Camera2Device::MetadataQueue::getToProducerInterface() {
141 return static_cast<camera2_frame_queue_dst_ops_t*>(this);
142}
143
144// Real interfaces
145status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
146 Mutex::Autolock l(mMutex);
147
148 mCount++;
149 mEntries.push_back(buf);
150 notEmpty.signal();
151
152 if (mSignalConsumer && mDevice != NULL) {
153 mSignalConsumer = false;
154
155 mMutex.unlock();
156 ALOGV("%s: Signaling consumer", __FUNCTION__);
157 mDevice->ops->notify_request_queue_not_empty(mDevice);
158 mMutex.lock();
159 }
160 return OK;
161}
162
163int Camera2Device::MetadataQueue::getBufferCount() {
164 Mutex::Autolock l(mMutex);
165 if (mStreamSlotCount > 0) {
166 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
167 }
168 return mCount;
169}
170
171status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
172 bool incrementCount)
173{
174 Mutex::Autolock l(mMutex);
175
176 if (mCount == 0) {
177 if (mStreamSlotCount == 0) {
178 ALOGV("%s: Empty", __FUNCTION__);
179 *buf = NULL;
180 mSignalConsumer = true;
181 return OK;
182 }
183 ALOGV("%s: Streaming %d frames to queue", __FUNCTION__,
184 mStreamSlotCount);
185
186 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
187 slotEntry != mStreamSlot.end();
188 slotEntry++ ) {
189 size_t entries = get_camera_metadata_entry_count(*slotEntry);
190 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
191
192 camera_metadata_t *copy =
193 allocate_camera_metadata(entries, dataBytes);
194 append_camera_metadata(copy, *slotEntry);
195 mEntries.push_back(copy);
196 }
197 mCount = mStreamSlotCount;
198 }
199 ALOGV("MetadataQueue: deque (%d buffers)", mCount);
200 camera_metadata_t *b = *(mEntries.begin());
201 mEntries.erase(mEntries.begin());
202
203 if (incrementCount) {
204 add_camera_metadata_entry(b,
205 ANDROID_REQUEST_FRAME_COUNT,
206 (void**)&mFrameCount, 1);
207 mFrameCount++;
208 }
209
210 *buf = b;
211 mCount--;
212
213 return OK;
214}
215
216status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
217{
218 Mutex::Autolock l(mMutex);
219 status_t res;
220 while (mCount == 0) {
221 res = notEmpty.waitRelative(mMutex,timeout);
222 if (res != OK) return res;
223 }
224 return OK;
225}
226
227status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
228{
229 Mutex::Autolock l(mMutex);
230 if (buf == NULL) {
231 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
232 mStreamSlotCount = 0;
233 return OK;
234 }
235 if (mStreamSlotCount > 1) {
236 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
237 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
238 mStreamSlotCount = 1;
239 }
240 if (mStreamSlotCount == 1) {
241 free_camera_metadata( *(mStreamSlot.begin()) );
242 *(mStreamSlot.begin()) = buf;
243 } else {
244 mStreamSlot.push_front(buf);
245 mStreamSlotCount = 1;
246 }
247 return OK;
248}
249
250status_t Camera2Device::MetadataQueue::setStreamSlot(
251 const List<camera_metadata_t*> &bufs)
252{
253 Mutex::Autolock l(mMutex);
254 if (mStreamSlotCount > 0) {
255 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
256 }
257 mStreamSlot = bufs;
258 mStreamSlotCount = mStreamSlot.size();
259
260 return OK;
261}
262
263status_t Camera2Device::MetadataQueue::freeBuffers(
264 List<camera_metadata_t*>::iterator start,
265 List<camera_metadata_t*>::iterator end)
266{
267 while (start != end) {
268 free_camera_metadata(*start);
269 start = mStreamSlot.erase(start);
270 }
271 return OK;
272}
273
274Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
275 const camera2_request_queue_src_ops_t *q)
276{
277 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
278 return const_cast<MetadataQueue*>(cmq);
279}
280
281Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
282 const camera2_frame_queue_dst_ops_t *q)
283{
284 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
285 return const_cast<MetadataQueue*>(cmq);
286}
287
288int Camera2Device::MetadataQueue::consumer_buffer_count(
289 const camera2_request_queue_src_ops_t *q)
290{
291 MetadataQueue *queue = getInstance(q);
292 return queue->getBufferCount();
293}
294
295int Camera2Device::MetadataQueue::consumer_dequeue(
296 const camera2_request_queue_src_ops_t *q,
297 camera_metadata_t **buffer)
298{
299 MetadataQueue *queue = getInstance(q);
300 return queue->dequeue(buffer, true);
301}
302
303int Camera2Device::MetadataQueue::consumer_free(
304 const camera2_request_queue_src_ops_t *q,
305 camera_metadata_t *old_buffer)
306{
307 MetadataQueue *queue = getInstance(q);
308 free_camera_metadata(old_buffer);
309 return OK;
310}
311
312int Camera2Device::MetadataQueue::producer_dequeue(
313 const camera2_frame_queue_dst_ops_t *q,
314 size_t entries, size_t bytes,
315 camera_metadata_t **buffer)
316{
317 camera_metadata_t *new_buffer =
318 allocate_camera_metadata(entries, bytes);
319 if (new_buffer == NULL) return NO_MEMORY;
320 *buffer = new_buffer;
321 return OK;
322}
323
324int Camera2Device::MetadataQueue::producer_cancel(
325 const camera2_frame_queue_dst_ops_t *q,
326 camera_metadata_t *old_buffer)
327{
328 free_camera_metadata(old_buffer);
329 return OK;
330}
331
332int Camera2Device::MetadataQueue::producer_enqueue(
333 const camera2_frame_queue_dst_ops_t *q,
334 camera_metadata_t *filled_buffer)
335{
336 MetadataQueue *queue = getInstance(q);
337 return queue->enqueue(filled_buffer);
338}
339
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700340
341}; // namespace android