blob: 9df7cd45b3cee5902027fa98c237aaf678594f7f [file] [log] [blame]
Yin-Chia Yeh4717c472017-02-13 10:56:40 -08001/*
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#define LOG_TAG "CameraHardwareInterface"
17//#define LOG_NDEBUG 0
18
19#include <inttypes.h>
Yin-Chia Yeh06760662017-04-17 17:37:03 -070020#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080021#include "CameraHardwareInterface.h"
22
23namespace android {
24
25using namespace hardware::camera::device::V1_0;
26using namespace hardware::camera::common::V1_0;
27using hardware::hidl_handle;
28
29CameraHardwareInterface::~CameraHardwareInterface()
30{
31 ALOGI("Destroying camera %s", mName.string());
32 if (mDevice) {
33 int rc = mDevice->common.close(&mDevice->common);
34 if (rc != OK)
35 ALOGE("Could not close camera %s: %d", mName.string(), rc);
36 }
37 if (mHidlDevice != nullptr) {
38 mHidlDevice->close();
39 mHidlDevice.clear();
40 cleanupCirculatingBuffers();
41 }
42}
43
44status_t CameraHardwareInterface::initialize(CameraModule *module)
45{
46 if (mHidlDevice != nullptr) {
47 ALOGE("%s: camera hardware interface has been initialized to HIDL path!", __FUNCTION__);
48 return INVALID_OPERATION;
49 }
50 ALOGI("Opening camera %s", mName.string());
51 camera_info info;
52 status_t res = module->getCameraInfo(atoi(mName.string()), &info);
53 if (res != OK) {
54 return res;
55 }
56
57 int rc = OK;
58 if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
59 info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
60 // Open higher version camera device as HAL1.0 device.
61 rc = module->openLegacy(mName.string(),
62 CAMERA_DEVICE_API_VERSION_1_0,
63 (hw_device_t **)&mDevice);
64 } else {
65 rc = module->open(mName.string(), (hw_device_t **)&mDevice);
66 }
67 if (rc != OK) {
68 ALOGE("Could not open camera %s: %d", mName.string(), rc);
69 return rc;
70 }
71 initHalPreviewWindow();
72 return rc;
73}
74
75status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
76 if (mDevice) {
77 ALOGE("%s: camera hardware interface has been initialized to libhardware path!",
78 __FUNCTION__);
79 return INVALID_OPERATION;
80 }
81
82 ALOGI("Opening camera %s", mName.string());
83
Steven Moreland5ff9c912017-03-09 23:13:00 -080084 status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080085 if (ret != OK) {
86 ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
87 }
88 return ret;
89}
90
91status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
92{
93 int rc = OK;
94 mPreviewScalingMode = scalingMode;
95 if (mPreviewWindow != nullptr) {
96 rc = native_window_set_scaling_mode(mPreviewWindow.get(),
97 scalingMode);
98 }
99 return rc;
100}
101
102status_t CameraHardwareInterface::setPreviewTransform(int transform) {
103 int rc = OK;
104 mPreviewTransform = transform;
105 if (mPreviewWindow != nullptr) {
106 rc = native_window_set_buffers_transform(mPreviewWindow.get(),
107 mPreviewTransform);
108 }
109 return rc;
110}
111
112/**
113 * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
114 */
115hardware::Return<void> CameraHardwareInterface::notifyCallback(
116 NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
117 sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
118 return hardware::Void();
119}
120
121hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
122 const hardware::hidl_handle& descriptor,
123 uint32_t bufferSize, uint32_t bufferCount) {
124 if (descriptor->numFds != 1) {
125 ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
126 __FUNCTION__, descriptor->numFds);
127 return 0;
128 }
129 if (descriptor->data[0] < 0) {
130 ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
131 __FUNCTION__, descriptor->data[0]);
132 return 0;
133 }
134
135 camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
136 sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
137 int memPoolId = camMem->mHeap->getHeapID();
138 if (memPoolId < 0) {
139 ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
140 return 0;
141 }
142 mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
143 return memPoolId;
144}
145
146hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
147 if (mHidlMemPoolMap.count(memId) == 0) {
148 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
149 return hardware::Void();
150 }
151 camera_memory_t* mem = mHidlMemPoolMap.at(memId);
152 sPutMemory(mem);
153 mHidlMemPoolMap.erase(memId);
154 return hardware::Void();
155}
156
157hardware::Return<void> CameraHardwareInterface::dataCallback(
158 DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
159 const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
160 if (mHidlMemPoolMap.count(data) == 0) {
161 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
162 return hardware::Void();
163 }
164 camera_frame_metadata_t md;
165 md.number_of_faces = metadata.faces.size();
166 md.faces = (camera_face_t*) metadata.faces.data();
167 sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
168 return hardware::Void();
169}
170
171hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
172 DataCallbackMsg msgType, uint32_t data,
173 uint32_t bufferIndex, int64_t timestamp) {
174 if (mHidlMemPoolMap.count(data) == 0) {
175 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
176 return hardware::Void();
177 }
178 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
179 return hardware::Void();
180}
181
182hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
183 DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
184 uint32_t bufferIndex, int64_t timestamp) {
185 if (mHidlMemPoolMap.count(data) == 0) {
186 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
187 return hardware::Void();
188 }
189 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
190 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
191 mem->mBuffers[bufferIndex]->pointer();
192 md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
193 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
194 return hardware::Void();
195}
196
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700197hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
198 DataCallbackMsg msgType,
199 const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
200 std::vector<android::HandleTimestampMessage> msgs;
201 msgs.reserve(messages.size());
202
203 for (const auto& hidl_msg : messages) {
204 if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
205 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
206 return hardware::Void();
207 }
208 sp<CameraHeapMemory> mem(
209 static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
210
211 if (hidl_msg.bufferIndex >= mem->mNumBufs) {
212 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
213 hidl_msg.bufferIndex, mem->mNumBufs);
214 return hardware::Void();
215 }
216 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
217 mem->mBuffers[hidl_msg.bufferIndex]->pointer();
218 md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
219
220 msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
221 }
222
223 mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
224 return hardware::Void();
225}
226
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800227std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
228 ANativeWindowBuffer* anb) {
229 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
230
231 buffer_handle_t& buf = anb->handle;
232 auto it = mBufferIdMap.find(buf);
233 if (it == mBufferIdMap.end()) {
234 uint64_t bufId = mNextBufferId++;
235 mBufferIdMap[buf] = bufId;
236 mReversedBufMap[bufId] = anb;
237 return std::make_pair(true, bufId);
238 } else {
239 return std::make_pair(false, it->second);
240 }
241}
242
243void CameraHardwareInterface::cleanupCirculatingBuffers() {
244 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
245 mBufferIdMap.clear();
246 mReversedBufMap.clear();
247}
248
249hardware::Return<void>
250CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
251 ANativeWindow *a = mPreviewWindow.get();
252 if (a == nullptr) {
253 ALOGE("%s: preview window is null", __FUNCTION__);
254 return hardware::Void();
255 }
256 ANativeWindowBuffer* anb;
257 int rc = native_window_dequeue_buffer_and_wait(a, &anb);
258 Status s = Status::INTERNAL_ERROR;
259 uint64_t bufferId = 0;
260 uint32_t stride = 0;
261 hidl_handle buf = nullptr;
262 if (rc == OK) {
263 s = Status::OK;
264 auto pair = getBufferId(anb);
265 buf = (pair.first) ? anb->handle : nullptr;
266 bufferId = pair.second;
267 stride = anb->stride;
268 }
269
270 _hidl_cb(s, bufferId, buf, stride);
271 return hardware::Void();
272}
273
274hardware::Return<Status>
275CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
276 ANativeWindow *a = mPreviewWindow.get();
277 if (a == nullptr) {
278 ALOGE("%s: preview window is null", __FUNCTION__);
279 return Status::INTERNAL_ERROR;
280 }
281 if (mReversedBufMap.count(bufferId) == 0) {
282 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
283 return Status::ILLEGAL_ARGUMENT;
284 }
285 int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
286 if (rc == 0) {
287 return Status::OK;
288 }
289 return Status::INTERNAL_ERROR;
290}
291
292hardware::Return<Status>
293CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
294 ANativeWindow *a = mPreviewWindow.get();
295 if (a == nullptr) {
296 ALOGE("%s: preview window is null", __FUNCTION__);
297 return Status::INTERNAL_ERROR;
298 }
299 if (mReversedBufMap.count(bufferId) == 0) {
300 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
301 return Status::ILLEGAL_ARGUMENT;
302 }
303 int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
304 if (rc == 0) {
305 return Status::OK;
306 }
307 return Status::INTERNAL_ERROR;
308}
309
310hardware::Return<Status>
311CameraHardwareInterface::setBufferCount(uint32_t count) {
312 ANativeWindow *a = mPreviewWindow.get();
313 if (a != nullptr) {
314 // Workaround for b/27039775
315 // Previously, setting the buffer count would reset the buffer
316 // queue's flag that allows for all buffers to be dequeued on the
317 // producer side, instead of just the producer's declared max count,
318 // if no filled buffers have yet been queued by the producer. This
319 // reset no longer happens, but some HALs depend on this behavior,
320 // so it needs to be maintained for HAL backwards compatibility.
321 // Simulate the prior behavior by disconnecting/reconnecting to the
322 // window and setting the values again. This has the drawback of
323 // actually causing memory reallocation, which may not have happened
324 // in the past.
325 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
326 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
327 if (mPreviewScalingMode != NOT_SET) {
328 native_window_set_scaling_mode(a, mPreviewScalingMode);
329 }
330 if (mPreviewTransform != NOT_SET) {
331 native_window_set_buffers_transform(a, mPreviewTransform);
332 }
333 if (mPreviewWidth != NOT_SET) {
334 native_window_set_buffers_dimensions(a,
335 mPreviewWidth, mPreviewHeight);
336 native_window_set_buffers_format(a, mPreviewFormat);
337 }
338 if (mPreviewUsage != 0) {
339 native_window_set_usage(a, mPreviewUsage);
340 }
341 if (mPreviewSwapInterval != NOT_SET) {
342 a->setSwapInterval(a, mPreviewSwapInterval);
343 }
344 if (mPreviewCrop.left != NOT_SET) {
345 native_window_set_crop(a, &(mPreviewCrop));
346 }
347 }
348 int rc = native_window_set_buffer_count(a, count);
349 if (rc == OK) {
350 cleanupCirculatingBuffers();
351 return Status::OK;
352 }
353 return Status::INTERNAL_ERROR;
354}
355
356hardware::Return<Status>
357CameraHardwareInterface::setBuffersGeometry(
358 uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
359 Status s = Status::INTERNAL_ERROR;
360 ANativeWindow *a = mPreviewWindow.get();
361 if (a == nullptr) {
362 ALOGE("%s: preview window is null", __FUNCTION__);
363 return s;
364 }
365 mPreviewWidth = w;
366 mPreviewHeight = h;
367 mPreviewFormat = (int) format;
368 int rc = native_window_set_buffers_dimensions(a, w, h);
369 if (rc == OK) {
370 rc = native_window_set_buffers_format(a, mPreviewFormat);
371 }
372 if (rc == OK) {
373 cleanupCirculatingBuffers();
374 s = Status::OK;
375 }
376 return s;
377}
378
379hardware::Return<Status>
380CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
381 Status s = Status::INTERNAL_ERROR;
382 ANativeWindow *a = mPreviewWindow.get();
383 if (a == nullptr) {
384 ALOGE("%s: preview window is null", __FUNCTION__);
385 return s;
386 }
387 mPreviewCrop.left = left;
388 mPreviewCrop.top = top;
389 mPreviewCrop.right = right;
390 mPreviewCrop.bottom = bottom;
391 int rc = native_window_set_crop(a, &mPreviewCrop);
392 if (rc == OK) {
393 s = Status::OK;
394 }
395 return s;
396}
397
398hardware::Return<Status>
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700399CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800400 Status s = Status::INTERNAL_ERROR;
401 ANativeWindow *a = mPreviewWindow.get();
402 if (a == nullptr) {
403 ALOGE("%s: preview window is null", __FUNCTION__);
404 return s;
405 }
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700406 mPreviewUsage = (int) usage;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800407 int rc = native_window_set_usage(a, mPreviewUsage);
408 if (rc == OK) {
409 cleanupCirculatingBuffers();
410 s = Status::OK;
411 }
412 return s;
413}
414
415hardware::Return<Status>
416CameraHardwareInterface::setSwapInterval(int32_t interval) {
417 Status s = Status::INTERNAL_ERROR;
418 ANativeWindow *a = mPreviewWindow.get();
419 if (a == nullptr) {
420 ALOGE("%s: preview window is null", __FUNCTION__);
421 return s;
422 }
423 mPreviewSwapInterval = interval;
424 int rc = a->setSwapInterval(a, interval);
425 if (rc == OK) {
426 s = Status::OK;
427 }
428 return s;
429}
430
431hardware::Return<void>
432CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
433 ANativeWindow *a = mPreviewWindow.get();
434 if (a == nullptr) {
435 ALOGE("%s: preview window is null", __FUNCTION__);
436 return hardware::Void();
437 }
438 int count = 0;
439 int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
440 Status s = Status::INTERNAL_ERROR;
441 if (rc == OK) {
442 s = Status::OK;
443 }
444 _hidl_cb(s, count);
445 return hardware::Void();
446}
447
448hardware::Return<Status>
449CameraHardwareInterface::setTimestamp(int64_t timestamp) {
450 Status s = Status::INTERNAL_ERROR;
451 ANativeWindow *a = mPreviewWindow.get();
452 if (a == nullptr) {
453 ALOGE("%s: preview window is null", __FUNCTION__);
454 return s;
455 }
456 int rc = native_window_set_buffers_timestamp(a, timestamp);
457 if (rc == OK) {
458 s = Status::OK;
459 }
460 return s;
461}
462
463status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
464{
465 ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
466 if (CC_LIKELY(mHidlDevice != nullptr)) {
467 mPreviewWindow = buf;
468 if (buf != nullptr) {
469 if (mPreviewScalingMode != NOT_SET) {
470 setPreviewScalingMode(mPreviewScalingMode);
471 }
472 if (mPreviewTransform != NOT_SET) {
473 setPreviewTransform(mPreviewTransform);
474 }
475 }
476 return CameraProviderManager::mapToStatusT(
477 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
478 } else if (mDevice) {
479 if (mDevice->ops->set_preview_window) {
480 mPreviewWindow = buf;
481 if (buf != nullptr) {
482 if (mPreviewScalingMode != NOT_SET) {
483 setPreviewScalingMode(mPreviewScalingMode);
484 }
485 if (mPreviewTransform != NOT_SET) {
486 setPreviewTransform(mPreviewTransform);
487 }
488 }
489 mHalPreviewWindow.user = this;
490 ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p",__FUNCTION__,
491 &mHalPreviewWindow, mHalPreviewWindow.user);
492 return mDevice->ops->set_preview_window(mDevice,
493 buf.get() ? &mHalPreviewWindow.nw : 0);
494 }
495 }
496 return INVALID_OPERATION;
497}
498
499void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
500 data_callback data_cb,
501 data_callback_timestamp data_cb_timestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700502 data_callback_timestamp_batch data_cb_timestamp_batch,
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800503 void* user)
504{
505 mNotifyCb = notify_cb;
506 mDataCb = data_cb;
507 mDataCbTimestamp = data_cb_timestamp;
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700508 mDataCbTimestampBatch = data_cb_timestamp_batch;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800509 mCbUser = user;
510
511 ALOGV("%s(%s)", __FUNCTION__, mName.string());
512
513 if (mDevice && mDevice->ops->set_callbacks) {
514 mDevice->ops->set_callbacks(mDevice,
515 sNotifyCb,
516 sDataCb,
517 sDataCbTimestamp,
518 sGetMemory,
519 this);
520 }
521}
522
523void CameraHardwareInterface::enableMsgType(int32_t msgType)
524{
525 ALOGV("%s(%s)", __FUNCTION__, mName.string());
526 if (CC_LIKELY(mHidlDevice != nullptr)) {
527 mHidlDevice->enableMsgType(msgType);
528 } else if (mDevice && mDevice->ops->enable_msg_type) {
529 mDevice->ops->enable_msg_type(mDevice, msgType);
530 }
531}
532
533void CameraHardwareInterface::disableMsgType(int32_t msgType)
534{
535 ALOGV("%s(%s)", __FUNCTION__, mName.string());
536 if (CC_LIKELY(mHidlDevice != nullptr)) {
537 mHidlDevice->disableMsgType(msgType);
538 } else if (mDevice && mDevice->ops->disable_msg_type) {
539 mDevice->ops->disable_msg_type(mDevice, msgType);
540 }
541}
542
543int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
544{
545 ALOGV("%s(%s)", __FUNCTION__, mName.string());
546 if (CC_LIKELY(mHidlDevice != nullptr)) {
547 return mHidlDevice->msgTypeEnabled(msgType);
548 } else if (mDevice && mDevice->ops->msg_type_enabled) {
549 return mDevice->ops->msg_type_enabled(mDevice, msgType);
550 }
551 return false;
552}
553
554status_t CameraHardwareInterface::startPreview()
555{
556 ALOGV("%s(%s)", __FUNCTION__, mName.string());
557 if (CC_LIKELY(mHidlDevice != nullptr)) {
558 return CameraProviderManager::mapToStatusT(
559 mHidlDevice->startPreview());
560 } else if (mDevice && mDevice->ops->start_preview) {
561 return mDevice->ops->start_preview(mDevice);
562 }
563 return INVALID_OPERATION;
564}
565
566void CameraHardwareInterface::stopPreview()
567{
568 ALOGV("%s(%s)", __FUNCTION__, mName.string());
569 if (CC_LIKELY(mHidlDevice != nullptr)) {
570 mHidlDevice->stopPreview();
571 } else if (mDevice && mDevice->ops->stop_preview) {
572 mDevice->ops->stop_preview(mDevice);
573 }
574}
575
576int CameraHardwareInterface::previewEnabled()
577{
578 ALOGV("%s(%s)", __FUNCTION__, mName.string());
579 if (CC_LIKELY(mHidlDevice != nullptr)) {
580 return mHidlDevice->previewEnabled();
581 } else if (mDevice && mDevice->ops->preview_enabled) {
582 return mDevice->ops->preview_enabled(mDevice);
583 }
584 return false;
585}
586
587status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
588{
589 ALOGV("%s(%s)", __FUNCTION__, mName.string());
590 if (CC_LIKELY(mHidlDevice != nullptr)) {
591 return CameraProviderManager::mapToStatusT(
592 mHidlDevice->storeMetaDataInBuffers(enable));
593 } else if (mDevice && mDevice->ops->store_meta_data_in_buffers) {
594 return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
595 }
596 return enable ? INVALID_OPERATION: OK;
597}
598
599status_t CameraHardwareInterface::startRecording()
600{
601 ALOGV("%s(%s)", __FUNCTION__, mName.string());
602 if (CC_LIKELY(mHidlDevice != nullptr)) {
603 return CameraProviderManager::mapToStatusT(
604 mHidlDevice->startRecording());
605 } else if (mDevice && mDevice->ops->start_recording) {
606 return mDevice->ops->start_recording(mDevice);
607 }
608 return INVALID_OPERATION;
609}
610
611/**
612 * Stop a previously started recording.
613 */
614void CameraHardwareInterface::stopRecording()
615{
616 ALOGV("%s(%s)", __FUNCTION__, mName.string());
617 if (CC_LIKELY(mHidlDevice != nullptr)) {
618 mHidlDevice->stopRecording();
619 } else if (mDevice && mDevice->ops->stop_recording) {
620 mDevice->ops->stop_recording(mDevice);
621 }
622}
623
624/**
625 * Returns true if recording is enabled.
626 */
627int CameraHardwareInterface::recordingEnabled()
628{
629 ALOGV("%s(%s)", __FUNCTION__, mName.string());
630 if (CC_LIKELY(mHidlDevice != nullptr)) {
631 return mHidlDevice->recordingEnabled();
632 } else if (mDevice && mDevice->ops->recording_enabled) {
633 return mDevice->ops->recording_enabled(mDevice);
634 }
635 return false;
636}
637
638void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
639{
640 ALOGV("%s(%s)", __FUNCTION__, mName.string());
641 ssize_t offset;
642 size_t size;
643 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
644 int heapId = heap->getHeapID();
645 int bufferIndex = offset / size;
646 if (CC_LIKELY(mHidlDevice != nullptr)) {
647 if (size == sizeof(VideoNativeHandleMetadata)) {
648 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
649 // Caching the handle here because md->pHandle will be subject to HAL's edit
650 native_handle_t* nh = md->pHandle;
651 hidl_handle frame = nh;
652 mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
653 native_handle_close(nh);
654 native_handle_delete(nh);
655 } else {
656 mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
657 }
658 } else if (mDevice && mDevice->ops->release_recording_frame) {
659 void *data = ((uint8_t *)heap->base()) + offset;
660 return mDevice->ops->release_recording_frame(mDevice, data);
661 }
662}
663
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700664void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
665{
666 ALOGV("%s(%s)", __FUNCTION__, mName.string());
667 size_t n = frames.size();
668 std::vector<VideoFrameMessage> msgs;
669 msgs.reserve(n);
670 for (auto& mem : frames) {
671 if (CC_LIKELY(mHidlDevice != nullptr)) {
672 ssize_t offset;
673 size_t size;
674 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
675 if (size == sizeof(VideoNativeHandleMetadata)) {
676 uint32_t heapId = heap->getHeapID();
677 uint32_t bufferIndex = offset / size;
678 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
679 // Caching the handle here because md->pHandle will be subject to HAL's edit
680 native_handle_t* nh = md->pHandle;
681 VideoFrameMessage msg;
682 msgs.push_back({nh, heapId, bufferIndex});
683 } else {
684 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
685 return;
686 }
687 } else {
688 ALOGE("Non HIDL mode do not support %s", __FUNCTION__);
689 return;
690 }
691 }
692
693 mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
694
695 for (auto& msg : msgs) {
696 native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
697 native_handle_close(nh);
698 native_handle_delete(nh);
699 }
700}
701
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800702status_t CameraHardwareInterface::autoFocus()
703{
704 ALOGV("%s(%s)", __FUNCTION__, mName.string());
705 if (CC_LIKELY(mHidlDevice != nullptr)) {
706 return CameraProviderManager::mapToStatusT(
707 mHidlDevice->autoFocus());
708 } else if (mDevice && mDevice->ops->auto_focus) {
709 return mDevice->ops->auto_focus(mDevice);
710 }
711 return INVALID_OPERATION;
712}
713
714status_t CameraHardwareInterface::cancelAutoFocus()
715{
716 ALOGV("%s(%s)", __FUNCTION__, mName.string());
717 if (CC_LIKELY(mHidlDevice != nullptr)) {
718 return CameraProviderManager::mapToStatusT(
719 mHidlDevice->cancelAutoFocus());
720 } else if (mDevice && mDevice->ops->cancel_auto_focus) {
721 return mDevice->ops->cancel_auto_focus(mDevice);
722 }
723 return INVALID_OPERATION;
724}
725
726status_t CameraHardwareInterface::takePicture()
727{
728 ALOGV("%s(%s)", __FUNCTION__, mName.string());
729 if (CC_LIKELY(mHidlDevice != nullptr)) {
730 return CameraProviderManager::mapToStatusT(
731 mHidlDevice->takePicture());
732 } else if (mDevice && mDevice->ops->take_picture) {
733 return mDevice->ops->take_picture(mDevice);
734 }
735 return INVALID_OPERATION;
736}
737
738status_t CameraHardwareInterface::cancelPicture()
739{
740 ALOGV("%s(%s)", __FUNCTION__, mName.string());
741 if (CC_LIKELY(mHidlDevice != nullptr)) {
742 return CameraProviderManager::mapToStatusT(
743 mHidlDevice->cancelPicture());
744 } else if (mDevice && mDevice->ops->cancel_picture) {
745 return mDevice->ops->cancel_picture(mDevice);
746 }
747 return INVALID_OPERATION;
748}
749
750status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
751{
752 ALOGV("%s(%s)", __FUNCTION__, mName.string());
753 if (CC_LIKELY(mHidlDevice != nullptr)) {
754 return CameraProviderManager::mapToStatusT(
755 mHidlDevice->setParameters(params.flatten().string()));
756 } else if (mDevice && mDevice->ops->set_parameters) {
757 return mDevice->ops->set_parameters(mDevice, params.flatten().string());
758 }
759 return INVALID_OPERATION;
760}
761
762CameraParameters CameraHardwareInterface::getParameters() const
763{
764 ALOGV("%s(%s)", __FUNCTION__, mName.string());
765 CameraParameters parms;
766 if (CC_LIKELY(mHidlDevice != nullptr)) {
767 hardware::hidl_string outParam;
768 mHidlDevice->getParameters(
769 [&outParam](const auto& outStr) {
770 outParam = outStr;
771 });
772 String8 tmp(outParam.c_str());
773 parms.unflatten(tmp);
774 } else if (mDevice && mDevice->ops->get_parameters) {
775 char *temp = mDevice->ops->get_parameters(mDevice);
776 String8 str_parms(temp);
777 if (mDevice->ops->put_parameters)
778 mDevice->ops->put_parameters(mDevice, temp);
779 else
780 free(temp);
781 parms.unflatten(str_parms);
782 }
783 return parms;
784}
785
786status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
787{
788 ALOGV("%s(%s)", __FUNCTION__, mName.string());
789 if (CC_LIKELY(mHidlDevice != nullptr)) {
790 return CameraProviderManager::mapToStatusT(
791 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
792 } else if (mDevice && mDevice->ops->send_command) {
793 return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
794 }
795 return INVALID_OPERATION;
796}
797
798/**
799 * Release the hardware resources owned by this object. Note that this is
800 * *not* done in the destructor.
801 */
802void CameraHardwareInterface::release() {
803 ALOGV("%s(%s)", __FUNCTION__, mName.string());
804 if (CC_LIKELY(mHidlDevice != nullptr)) {
805 mHidlDevice->close();
806 mHidlDevice.clear();
807 } else if (mDevice && mDevice->ops->release) {
808 mDevice->ops->release(mDevice);
809 }
810}
811
812/**
813 * Dump state of the camera hardware
814 */
815status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
816{
817 ALOGV("%s(%s)", __FUNCTION__, mName.string());
818 if (CC_LIKELY(mHidlDevice != nullptr)) {
819 native_handle_t* handle = native_handle_create(1,0);
820 handle->data[0] = fd;
821 Status s = mHidlDevice->dumpState(handle);
822 native_handle_delete(handle);
823 return CameraProviderManager::mapToStatusT(s);
824 } else if (mDevice && mDevice->ops->dump) {
825 return mDevice->ops->dump(mDevice, fd);
826 }
827 return OK; // It's fine if the HAL doesn't implement dump()
828}
829
830/**
831 * Methods for legacy (non-HIDL) path follows
832 */
833void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
834 int32_t ext2, void *user)
835{
836 ALOGV("%s", __FUNCTION__);
837 CameraHardwareInterface *object =
838 static_cast<CameraHardwareInterface *>(user);
839 object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
840}
841
842void CameraHardwareInterface::sDataCb(int32_t msg_type,
843 const camera_memory_t *data, unsigned int index,
844 camera_frame_metadata_t *metadata,
845 void *user)
846{
847 ALOGV("%s", __FUNCTION__);
848 CameraHardwareInterface *object =
849 static_cast<CameraHardwareInterface *>(user);
850 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
851 if (index >= mem->mNumBufs) {
852 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
853 index, mem->mNumBufs);
854 return;
855 }
856 object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
857}
858
859void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
860 const camera_memory_t *data, unsigned index,
861 void *user)
862{
863 ALOGV("%s", __FUNCTION__);
864 CameraHardwareInterface *object =
865 static_cast<CameraHardwareInterface *>(user);
866 // Start refcounting the heap object from here on. When the clients
867 // drop all references, it will be destroyed (as well as the enclosed
868 // MemoryHeapBase.
869 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
870 if (index >= mem->mNumBufs) {
871 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
872 index, mem->mNumBufs);
873 return;
874 }
875 object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
876}
877
878camera_memory_t* CameraHardwareInterface::sGetMemory(
879 int fd, size_t buf_size, uint_t num_bufs,
880 void *user __attribute__((unused)))
881{
882 CameraHeapMemory *mem;
883 if (fd < 0) {
884 mem = new CameraHeapMemory(buf_size, num_bufs);
885 } else {
886 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
887 }
888 mem->incStrong(mem);
889 return &mem->handle;
890}
891
892void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
893{
894 if (!data) {
895 return;
896 }
897
898 CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
899 mem->decStrong(mem);
900}
901
902ANativeWindow* CameraHardwareInterface::sToAnw(void *user)
903{
904 CameraHardwareInterface *object =
905 reinterpret_cast<CameraHardwareInterface *>(user);
906 return object->mPreviewWindow.get();
907}
908#define anw(n) sToAnw(((struct camera_preview_window *)(n))->user)
909#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
910 ((struct camera_preview_window *)(n))->user)
911
912int CameraHardwareInterface::sDequeueBuffer(struct preview_stream_ops* w,
913 buffer_handle_t** buffer, int *stride)
914{
915 int rc;
916 ANativeWindow *a = anw(w);
917 ANativeWindowBuffer* anb;
918 rc = native_window_dequeue_buffer_and_wait(a, &anb);
919 if (rc == OK) {
920 *buffer = &anb->handle;
921 *stride = anb->stride;
922 }
923 return rc;
924}
925
926#ifndef container_of
927#define container_of(ptr, type, member) ({ \
928 const __typeof__(((type *) 0)->member) *__mptr = (ptr); \
929 (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
930#endif
931
932int CameraHardwareInterface::sLockBuffer(struct preview_stream_ops* w,
933 buffer_handle_t* /*buffer*/)
934{
935 ANativeWindow *a = anw(w);
936 (void)a;
937 return 0;
938}
939
940int CameraHardwareInterface::sEnqueueBuffer(struct preview_stream_ops* w,
941 buffer_handle_t* buffer)
942{
943 ANativeWindow *a = anw(w);
944 return a->queueBuffer(a,
945 container_of(buffer, ANativeWindowBuffer, handle), -1);
946}
947
948int CameraHardwareInterface::sCancelBuffer(struct preview_stream_ops* w,
949 buffer_handle_t* buffer)
950{
951 ANativeWindow *a = anw(w);
952 return a->cancelBuffer(a,
953 container_of(buffer, ANativeWindowBuffer, handle), -1);
954}
955
956int CameraHardwareInterface::sSetBufferCount(struct preview_stream_ops* w, int count)
957{
958 ANativeWindow *a = anw(w);
959
960 if (a != nullptr) {
961 // Workaround for b/27039775
962 // Previously, setting the buffer count would reset the buffer
963 // queue's flag that allows for all buffers to be dequeued on the
964 // producer side, instead of just the producer's declared max count,
965 // if no filled buffers have yet been queued by the producer. This
966 // reset no longer happens, but some HALs depend on this behavior,
967 // so it needs to be maintained for HAL backwards compatibility.
968 // Simulate the prior behavior by disconnecting/reconnecting to the
969 // window and setting the values again. This has the drawback of
970 // actually causing memory reallocation, which may not have happened
971 // in the past.
972 CameraHardwareInterface *hw = hwi(w);
973 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
974 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
975 if (hw->mPreviewScalingMode != NOT_SET) {
976 native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
977 }
978 if (hw->mPreviewTransform != NOT_SET) {
979 native_window_set_buffers_transform(a, hw->mPreviewTransform);
980 }
981 if (hw->mPreviewWidth != NOT_SET) {
982 native_window_set_buffers_dimensions(a,
983 hw->mPreviewWidth, hw->mPreviewHeight);
984 native_window_set_buffers_format(a, hw->mPreviewFormat);
985 }
986 if (hw->mPreviewUsage != 0) {
987 native_window_set_usage(a, hw->mPreviewUsage);
988 }
989 if (hw->mPreviewSwapInterval != NOT_SET) {
990 a->setSwapInterval(a, hw->mPreviewSwapInterval);
991 }
992 if (hw->mPreviewCrop.left != NOT_SET) {
993 native_window_set_crop(a, &(hw->mPreviewCrop));
994 }
995 }
996
997 return native_window_set_buffer_count(a, count);
998}
999
1000int CameraHardwareInterface::sSetBuffersGeometry(struct preview_stream_ops* w,
1001 int width, int height, int format)
1002{
1003 int rc;
1004 ANativeWindow *a = anw(w);
1005 CameraHardwareInterface *hw = hwi(w);
1006 hw->mPreviewWidth = width;
1007 hw->mPreviewHeight = height;
1008 hw->mPreviewFormat = format;
1009 rc = native_window_set_buffers_dimensions(a, width, height);
1010 if (rc == OK) {
1011 rc = native_window_set_buffers_format(a, format);
1012 }
1013 return rc;
1014}
1015
1016int CameraHardwareInterface::sSetCrop(struct preview_stream_ops *w,
1017 int left, int top, int right, int bottom)
1018{
1019 ANativeWindow *a = anw(w);
1020 CameraHardwareInterface *hw = hwi(w);
1021 hw->mPreviewCrop.left = left;
1022 hw->mPreviewCrop.top = top;
1023 hw->mPreviewCrop.right = right;
1024 hw->mPreviewCrop.bottom = bottom;
1025 return native_window_set_crop(a, &(hw->mPreviewCrop));
1026}
1027
1028int CameraHardwareInterface::sSetTimestamp(struct preview_stream_ops *w,
1029 int64_t timestamp) {
1030 ANativeWindow *a = anw(w);
1031 return native_window_set_buffers_timestamp(a, timestamp);
1032}
1033
1034int CameraHardwareInterface::sSetUsage(struct preview_stream_ops* w, int usage)
1035{
1036 ANativeWindow *a = anw(w);
1037 CameraHardwareInterface *hw = hwi(w);
1038 hw->mPreviewUsage = usage;
1039 return native_window_set_usage(a, usage);
1040}
1041
1042int CameraHardwareInterface::sSetSwapInterval(struct preview_stream_ops *w, int interval)
1043{
1044 ANativeWindow *a = anw(w);
1045 CameraHardwareInterface *hw = hwi(w);
1046 hw->mPreviewSwapInterval = interval;
1047 return a->setSwapInterval(a, interval);
1048}
1049
1050int CameraHardwareInterface::sGetMinUndequeuedBufferCount(
1051 const struct preview_stream_ops *w,
1052 int *count)
1053{
1054 ANativeWindow *a = anw(w);
1055 return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
1056}
1057
1058void CameraHardwareInterface::initHalPreviewWindow()
1059{
1060 mHalPreviewWindow.nw.cancel_buffer = sCancelBuffer;
1061 mHalPreviewWindow.nw.lock_buffer = sLockBuffer;
1062 mHalPreviewWindow.nw.dequeue_buffer = sDequeueBuffer;
1063 mHalPreviewWindow.nw.enqueue_buffer = sEnqueueBuffer;
1064 mHalPreviewWindow.nw.set_buffer_count = sSetBufferCount;
1065 mHalPreviewWindow.nw.set_buffers_geometry = sSetBuffersGeometry;
1066 mHalPreviewWindow.nw.set_crop = sSetCrop;
1067 mHalPreviewWindow.nw.set_timestamp = sSetTimestamp;
1068 mHalPreviewWindow.nw.set_usage = sSetUsage;
1069 mHalPreviewWindow.nw.set_swap_interval = sSetSwapInterval;
1070
1071 mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
1072 sGetMinUndequeuedBufferCount;
1073}
1074
1075}; // namespace android