blob: 991b50ffffe97a99d97abfaf3c6cd73543f6c117 [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());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080032 if (mHidlDevice != nullptr) {
33 mHidlDevice->close();
34 mHidlDevice.clear();
35 cleanupCirculatingBuffers();
36 }
37}
38
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080039status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080040 ALOGI("Opening camera %s", mName.string());
41
Steven Moreland5ff9c912017-03-09 23:13:00 -080042 status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -080043 if (ret != OK) {
44 ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
45 }
46 return ret;
47}
48
49status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
50{
51 int rc = OK;
52 mPreviewScalingMode = scalingMode;
53 if (mPreviewWindow != nullptr) {
54 rc = native_window_set_scaling_mode(mPreviewWindow.get(),
55 scalingMode);
56 }
57 return rc;
58}
59
60status_t CameraHardwareInterface::setPreviewTransform(int transform) {
61 int rc = OK;
62 mPreviewTransform = transform;
63 if (mPreviewWindow != nullptr) {
64 rc = native_window_set_buffers_transform(mPreviewWindow.get(),
65 mPreviewTransform);
66 }
67 return rc;
68}
69
70/**
71 * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
72 */
73hardware::Return<void> CameraHardwareInterface::notifyCallback(
74 NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
75 sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
76 return hardware::Void();
77}
78
79hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
80 const hardware::hidl_handle& descriptor,
81 uint32_t bufferSize, uint32_t bufferCount) {
82 if (descriptor->numFds != 1) {
83 ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
84 __FUNCTION__, descriptor->numFds);
85 return 0;
86 }
87 if (descriptor->data[0] < 0) {
88 ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
89 __FUNCTION__, descriptor->data[0]);
90 return 0;
91 }
92
93 camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
94 sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
95 int memPoolId = camMem->mHeap->getHeapID();
96 if (memPoolId < 0) {
97 ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
98 return 0;
99 }
100 mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
101 return memPoolId;
102}
103
104hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
105 if (mHidlMemPoolMap.count(memId) == 0) {
106 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
107 return hardware::Void();
108 }
109 camera_memory_t* mem = mHidlMemPoolMap.at(memId);
110 sPutMemory(mem);
111 mHidlMemPoolMap.erase(memId);
112 return hardware::Void();
113}
114
115hardware::Return<void> CameraHardwareInterface::dataCallback(
116 DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
117 const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
118 if (mHidlMemPoolMap.count(data) == 0) {
119 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
120 return hardware::Void();
121 }
122 camera_frame_metadata_t md;
123 md.number_of_faces = metadata.faces.size();
124 md.faces = (camera_face_t*) metadata.faces.data();
125 sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
126 return hardware::Void();
127}
128
129hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
130 DataCallbackMsg msgType, uint32_t data,
131 uint32_t bufferIndex, int64_t timestamp) {
132 if (mHidlMemPoolMap.count(data) == 0) {
133 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
134 return hardware::Void();
135 }
136 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
137 return hardware::Void();
138}
139
140hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
141 DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
142 uint32_t bufferIndex, int64_t timestamp) {
143 if (mHidlMemPoolMap.count(data) == 0) {
144 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
145 return hardware::Void();
146 }
147 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
148 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
149 mem->mBuffers[bufferIndex]->pointer();
150 md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
151 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
152 return hardware::Void();
153}
154
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700155hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
156 DataCallbackMsg msgType,
157 const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
158 std::vector<android::HandleTimestampMessage> msgs;
159 msgs.reserve(messages.size());
160
161 for (const auto& hidl_msg : messages) {
162 if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
163 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
164 return hardware::Void();
165 }
166 sp<CameraHeapMemory> mem(
167 static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
168
169 if (hidl_msg.bufferIndex >= mem->mNumBufs) {
170 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
171 hidl_msg.bufferIndex, mem->mNumBufs);
172 return hardware::Void();
173 }
174 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
175 mem->mBuffers[hidl_msg.bufferIndex]->pointer();
176 md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
177
178 msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
179 }
180
181 mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
182 return hardware::Void();
183}
184
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800185std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
186 ANativeWindowBuffer* anb) {
187 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
188
189 buffer_handle_t& buf = anb->handle;
190 auto it = mBufferIdMap.find(buf);
191 if (it == mBufferIdMap.end()) {
192 uint64_t bufId = mNextBufferId++;
193 mBufferIdMap[buf] = bufId;
194 mReversedBufMap[bufId] = anb;
195 return std::make_pair(true, bufId);
196 } else {
197 return std::make_pair(false, it->second);
198 }
199}
200
201void CameraHardwareInterface::cleanupCirculatingBuffers() {
202 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
203 mBufferIdMap.clear();
204 mReversedBufMap.clear();
205}
206
207hardware::Return<void>
208CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
209 ANativeWindow *a = mPreviewWindow.get();
210 if (a == nullptr) {
211 ALOGE("%s: preview window is null", __FUNCTION__);
212 return hardware::Void();
213 }
214 ANativeWindowBuffer* anb;
215 int rc = native_window_dequeue_buffer_and_wait(a, &anb);
216 Status s = Status::INTERNAL_ERROR;
217 uint64_t bufferId = 0;
218 uint32_t stride = 0;
219 hidl_handle buf = nullptr;
220 if (rc == OK) {
221 s = Status::OK;
222 auto pair = getBufferId(anb);
223 buf = (pair.first) ? anb->handle : nullptr;
224 bufferId = pair.second;
225 stride = anb->stride;
226 }
227
228 _hidl_cb(s, bufferId, buf, stride);
229 return hardware::Void();
230}
231
232hardware::Return<Status>
233CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
234 ANativeWindow *a = mPreviewWindow.get();
235 if (a == nullptr) {
236 ALOGE("%s: preview window is null", __FUNCTION__);
237 return Status::INTERNAL_ERROR;
238 }
239 if (mReversedBufMap.count(bufferId) == 0) {
240 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
241 return Status::ILLEGAL_ARGUMENT;
242 }
243 int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
244 if (rc == 0) {
245 return Status::OK;
246 }
247 return Status::INTERNAL_ERROR;
248}
249
250hardware::Return<Status>
251CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
252 ANativeWindow *a = mPreviewWindow.get();
253 if (a == nullptr) {
254 ALOGE("%s: preview window is null", __FUNCTION__);
255 return Status::INTERNAL_ERROR;
256 }
257 if (mReversedBufMap.count(bufferId) == 0) {
258 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
259 return Status::ILLEGAL_ARGUMENT;
260 }
261 int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
262 if (rc == 0) {
263 return Status::OK;
264 }
265 return Status::INTERNAL_ERROR;
266}
267
268hardware::Return<Status>
269CameraHardwareInterface::setBufferCount(uint32_t count) {
270 ANativeWindow *a = mPreviewWindow.get();
271 if (a != nullptr) {
272 // Workaround for b/27039775
273 // Previously, setting the buffer count would reset the buffer
274 // queue's flag that allows for all buffers to be dequeued on the
275 // producer side, instead of just the producer's declared max count,
276 // if no filled buffers have yet been queued by the producer. This
277 // reset no longer happens, but some HALs depend on this behavior,
278 // so it needs to be maintained for HAL backwards compatibility.
279 // Simulate the prior behavior by disconnecting/reconnecting to the
280 // window and setting the values again. This has the drawback of
281 // actually causing memory reallocation, which may not have happened
282 // in the past.
283 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
284 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
285 if (mPreviewScalingMode != NOT_SET) {
286 native_window_set_scaling_mode(a, mPreviewScalingMode);
287 }
288 if (mPreviewTransform != NOT_SET) {
289 native_window_set_buffers_transform(a, mPreviewTransform);
290 }
291 if (mPreviewWidth != NOT_SET) {
292 native_window_set_buffers_dimensions(a,
293 mPreviewWidth, mPreviewHeight);
294 native_window_set_buffers_format(a, mPreviewFormat);
295 }
296 if (mPreviewUsage != 0) {
297 native_window_set_usage(a, mPreviewUsage);
298 }
299 if (mPreviewSwapInterval != NOT_SET) {
300 a->setSwapInterval(a, mPreviewSwapInterval);
301 }
302 if (mPreviewCrop.left != NOT_SET) {
303 native_window_set_crop(a, &(mPreviewCrop));
304 }
305 }
306 int rc = native_window_set_buffer_count(a, count);
307 if (rc == OK) {
308 cleanupCirculatingBuffers();
309 return Status::OK;
310 }
311 return Status::INTERNAL_ERROR;
312}
313
314hardware::Return<Status>
315CameraHardwareInterface::setBuffersGeometry(
316 uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
317 Status s = Status::INTERNAL_ERROR;
318 ANativeWindow *a = mPreviewWindow.get();
319 if (a == nullptr) {
320 ALOGE("%s: preview window is null", __FUNCTION__);
321 return s;
322 }
323 mPreviewWidth = w;
324 mPreviewHeight = h;
325 mPreviewFormat = (int) format;
326 int rc = native_window_set_buffers_dimensions(a, w, h);
327 if (rc == OK) {
328 rc = native_window_set_buffers_format(a, mPreviewFormat);
329 }
330 if (rc == OK) {
331 cleanupCirculatingBuffers();
332 s = Status::OK;
333 }
334 return s;
335}
336
337hardware::Return<Status>
338CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
339 Status s = Status::INTERNAL_ERROR;
340 ANativeWindow *a = mPreviewWindow.get();
341 if (a == nullptr) {
342 ALOGE("%s: preview window is null", __FUNCTION__);
343 return s;
344 }
345 mPreviewCrop.left = left;
346 mPreviewCrop.top = top;
347 mPreviewCrop.right = right;
348 mPreviewCrop.bottom = bottom;
349 int rc = native_window_set_crop(a, &mPreviewCrop);
350 if (rc == OK) {
351 s = Status::OK;
352 }
353 return s;
354}
355
356hardware::Return<Status>
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700357CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800358 Status s = Status::INTERNAL_ERROR;
359 ANativeWindow *a = mPreviewWindow.get();
360 if (a == nullptr) {
361 ALOGE("%s: preview window is null", __FUNCTION__);
362 return s;
363 }
Emilian Peev050f5dc2017-05-18 14:43:56 +0100364 mPreviewUsage = static_cast<uint64_t> (usage);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800365 int rc = native_window_set_usage(a, mPreviewUsage);
366 if (rc == OK) {
367 cleanupCirculatingBuffers();
368 s = Status::OK;
369 }
370 return s;
371}
372
373hardware::Return<Status>
374CameraHardwareInterface::setSwapInterval(int32_t interval) {
375 Status s = Status::INTERNAL_ERROR;
376 ANativeWindow *a = mPreviewWindow.get();
377 if (a == nullptr) {
378 ALOGE("%s: preview window is null", __FUNCTION__);
379 return s;
380 }
381 mPreviewSwapInterval = interval;
382 int rc = a->setSwapInterval(a, interval);
383 if (rc == OK) {
384 s = Status::OK;
385 }
386 return s;
387}
388
389hardware::Return<void>
390CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
391 ANativeWindow *a = mPreviewWindow.get();
392 if (a == nullptr) {
393 ALOGE("%s: preview window is null", __FUNCTION__);
394 return hardware::Void();
395 }
396 int count = 0;
397 int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
398 Status s = Status::INTERNAL_ERROR;
399 if (rc == OK) {
400 s = Status::OK;
401 }
402 _hidl_cb(s, count);
403 return hardware::Void();
404}
405
406hardware::Return<Status>
407CameraHardwareInterface::setTimestamp(int64_t timestamp) {
408 Status s = Status::INTERNAL_ERROR;
409 ANativeWindow *a = mPreviewWindow.get();
410 if (a == nullptr) {
411 ALOGE("%s: preview window is null", __FUNCTION__);
412 return s;
413 }
414 int rc = native_window_set_buffers_timestamp(a, timestamp);
415 if (rc == OK) {
416 s = Status::OK;
417 }
418 return s;
419}
420
421status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
422{
423 ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
424 if (CC_LIKELY(mHidlDevice != nullptr)) {
425 mPreviewWindow = buf;
426 if (buf != nullptr) {
427 if (mPreviewScalingMode != NOT_SET) {
428 setPreviewScalingMode(mPreviewScalingMode);
429 }
430 if (mPreviewTransform != NOT_SET) {
431 setPreviewTransform(mPreviewTransform);
432 }
433 }
434 return CameraProviderManager::mapToStatusT(
435 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800436 }
437 return INVALID_OPERATION;
438}
439
440void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
441 data_callback data_cb,
442 data_callback_timestamp data_cb_timestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700443 data_callback_timestamp_batch data_cb_timestamp_batch,
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800444 void* user)
445{
446 mNotifyCb = notify_cb;
447 mDataCb = data_cb;
448 mDataCbTimestamp = data_cb_timestamp;
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700449 mDataCbTimestampBatch = data_cb_timestamp_batch;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800450 mCbUser = user;
451
452 ALOGV("%s(%s)", __FUNCTION__, mName.string());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800453}
454
455void CameraHardwareInterface::enableMsgType(int32_t msgType)
456{
457 ALOGV("%s(%s)", __FUNCTION__, mName.string());
458 if (CC_LIKELY(mHidlDevice != nullptr)) {
459 mHidlDevice->enableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800460 }
461}
462
463void CameraHardwareInterface::disableMsgType(int32_t msgType)
464{
465 ALOGV("%s(%s)", __FUNCTION__, mName.string());
466 if (CC_LIKELY(mHidlDevice != nullptr)) {
467 mHidlDevice->disableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800468 }
469}
470
471int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
472{
473 ALOGV("%s(%s)", __FUNCTION__, mName.string());
474 if (CC_LIKELY(mHidlDevice != nullptr)) {
475 return mHidlDevice->msgTypeEnabled(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800476 }
477 return false;
478}
479
480status_t CameraHardwareInterface::startPreview()
481{
482 ALOGV("%s(%s)", __FUNCTION__, mName.string());
483 if (CC_LIKELY(mHidlDevice != nullptr)) {
484 return CameraProviderManager::mapToStatusT(
485 mHidlDevice->startPreview());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800486 }
487 return INVALID_OPERATION;
488}
489
490void CameraHardwareInterface::stopPreview()
491{
492 ALOGV("%s(%s)", __FUNCTION__, mName.string());
493 if (CC_LIKELY(mHidlDevice != nullptr)) {
494 mHidlDevice->stopPreview();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800495 }
496}
497
498int CameraHardwareInterface::previewEnabled()
499{
500 ALOGV("%s(%s)", __FUNCTION__, mName.string());
501 if (CC_LIKELY(mHidlDevice != nullptr)) {
502 return mHidlDevice->previewEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800503 }
504 return false;
505}
506
507status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
508{
509 ALOGV("%s(%s)", __FUNCTION__, mName.string());
510 if (CC_LIKELY(mHidlDevice != nullptr)) {
511 return CameraProviderManager::mapToStatusT(
512 mHidlDevice->storeMetaDataInBuffers(enable));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800513 }
514 return enable ? INVALID_OPERATION: OK;
515}
516
517status_t CameraHardwareInterface::startRecording()
518{
519 ALOGV("%s(%s)", __FUNCTION__, mName.string());
520 if (CC_LIKELY(mHidlDevice != nullptr)) {
521 return CameraProviderManager::mapToStatusT(
522 mHidlDevice->startRecording());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800523 }
524 return INVALID_OPERATION;
525}
526
527/**
528 * Stop a previously started recording.
529 */
530void CameraHardwareInterface::stopRecording()
531{
532 ALOGV("%s(%s)", __FUNCTION__, mName.string());
533 if (CC_LIKELY(mHidlDevice != nullptr)) {
534 mHidlDevice->stopRecording();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800535 }
536}
537
538/**
539 * Returns true if recording is enabled.
540 */
541int CameraHardwareInterface::recordingEnabled()
542{
543 ALOGV("%s(%s)", __FUNCTION__, mName.string());
544 if (CC_LIKELY(mHidlDevice != nullptr)) {
545 return mHidlDevice->recordingEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800546 }
547 return false;
548}
549
550void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
551{
552 ALOGV("%s(%s)", __FUNCTION__, mName.string());
553 ssize_t offset;
554 size_t size;
555 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
556 int heapId = heap->getHeapID();
557 int bufferIndex = offset / size;
558 if (CC_LIKELY(mHidlDevice != nullptr)) {
559 if (size == sizeof(VideoNativeHandleMetadata)) {
560 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
561 // Caching the handle here because md->pHandle will be subject to HAL's edit
562 native_handle_t* nh = md->pHandle;
563 hidl_handle frame = nh;
564 mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
565 native_handle_close(nh);
566 native_handle_delete(nh);
567 } else {
568 mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
569 }
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800570 }
571}
572
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700573void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
574{
575 ALOGV("%s(%s)", __FUNCTION__, mName.string());
576 size_t n = frames.size();
577 std::vector<VideoFrameMessage> msgs;
578 msgs.reserve(n);
579 for (auto& mem : frames) {
580 if (CC_LIKELY(mHidlDevice != nullptr)) {
581 ssize_t offset;
582 size_t size;
583 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
584 if (size == sizeof(VideoNativeHandleMetadata)) {
585 uint32_t heapId = heap->getHeapID();
586 uint32_t bufferIndex = offset / size;
587 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
588 // Caching the handle here because md->pHandle will be subject to HAL's edit
589 native_handle_t* nh = md->pHandle;
590 VideoFrameMessage msg;
591 msgs.push_back({nh, heapId, bufferIndex});
592 } else {
593 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
594 return;
595 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700596 }
597 }
598
599 mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
600
601 for (auto& msg : msgs) {
602 native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
603 native_handle_close(nh);
604 native_handle_delete(nh);
605 }
606}
607
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800608status_t CameraHardwareInterface::autoFocus()
609{
610 ALOGV("%s(%s)", __FUNCTION__, mName.string());
611 if (CC_LIKELY(mHidlDevice != nullptr)) {
612 return CameraProviderManager::mapToStatusT(
613 mHidlDevice->autoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800614 }
615 return INVALID_OPERATION;
616}
617
618status_t CameraHardwareInterface::cancelAutoFocus()
619{
620 ALOGV("%s(%s)", __FUNCTION__, mName.string());
621 if (CC_LIKELY(mHidlDevice != nullptr)) {
622 return CameraProviderManager::mapToStatusT(
623 mHidlDevice->cancelAutoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800624 }
625 return INVALID_OPERATION;
626}
627
628status_t CameraHardwareInterface::takePicture()
629{
630 ALOGV("%s(%s)", __FUNCTION__, mName.string());
631 if (CC_LIKELY(mHidlDevice != nullptr)) {
632 return CameraProviderManager::mapToStatusT(
633 mHidlDevice->takePicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800634 }
635 return INVALID_OPERATION;
636}
637
638status_t CameraHardwareInterface::cancelPicture()
639{
640 ALOGV("%s(%s)", __FUNCTION__, mName.string());
641 if (CC_LIKELY(mHidlDevice != nullptr)) {
642 return CameraProviderManager::mapToStatusT(
643 mHidlDevice->cancelPicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800644 }
645 return INVALID_OPERATION;
646}
647
648status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
649{
650 ALOGV("%s(%s)", __FUNCTION__, mName.string());
651 if (CC_LIKELY(mHidlDevice != nullptr)) {
652 return CameraProviderManager::mapToStatusT(
653 mHidlDevice->setParameters(params.flatten().string()));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800654 }
655 return INVALID_OPERATION;
656}
657
658CameraParameters CameraHardwareInterface::getParameters() const
659{
660 ALOGV("%s(%s)", __FUNCTION__, mName.string());
661 CameraParameters parms;
662 if (CC_LIKELY(mHidlDevice != nullptr)) {
663 hardware::hidl_string outParam;
664 mHidlDevice->getParameters(
665 [&outParam](const auto& outStr) {
666 outParam = outStr;
667 });
668 String8 tmp(outParam.c_str());
669 parms.unflatten(tmp);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800670 }
671 return parms;
672}
673
674status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
675{
676 ALOGV("%s(%s)", __FUNCTION__, mName.string());
677 if (CC_LIKELY(mHidlDevice != nullptr)) {
678 return CameraProviderManager::mapToStatusT(
679 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800680 }
681 return INVALID_OPERATION;
682}
683
684/**
685 * Release the hardware resources owned by this object. Note that this is
686 * *not* done in the destructor.
687 */
688void CameraHardwareInterface::release() {
689 ALOGV("%s(%s)", __FUNCTION__, mName.string());
690 if (CC_LIKELY(mHidlDevice != nullptr)) {
691 mHidlDevice->close();
692 mHidlDevice.clear();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800693 }
694}
695
696/**
697 * Dump state of the camera hardware
698 */
699status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
700{
701 ALOGV("%s(%s)", __FUNCTION__, mName.string());
702 if (CC_LIKELY(mHidlDevice != nullptr)) {
703 native_handle_t* handle = native_handle_create(1,0);
704 handle->data[0] = fd;
705 Status s = mHidlDevice->dumpState(handle);
706 native_handle_delete(handle);
707 return CameraProviderManager::mapToStatusT(s);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800708 }
709 return OK; // It's fine if the HAL doesn't implement dump()
710}
711
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800712void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
713 int32_t ext2, void *user)
714{
715 ALOGV("%s", __FUNCTION__);
716 CameraHardwareInterface *object =
717 static_cast<CameraHardwareInterface *>(user);
718 object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
719}
720
721void CameraHardwareInterface::sDataCb(int32_t msg_type,
722 const camera_memory_t *data, unsigned int index,
723 camera_frame_metadata_t *metadata,
724 void *user)
725{
726 ALOGV("%s", __FUNCTION__);
727 CameraHardwareInterface *object =
728 static_cast<CameraHardwareInterface *>(user);
729 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
730 if (index >= mem->mNumBufs) {
731 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
732 index, mem->mNumBufs);
733 return;
734 }
735 object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
736}
737
738void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
739 const camera_memory_t *data, unsigned index,
740 void *user)
741{
742 ALOGV("%s", __FUNCTION__);
743 CameraHardwareInterface *object =
744 static_cast<CameraHardwareInterface *>(user);
745 // Start refcounting the heap object from here on. When the clients
746 // drop all references, it will be destroyed (as well as the enclosed
747 // MemoryHeapBase.
748 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
749 if (index >= mem->mNumBufs) {
750 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
751 index, mem->mNumBufs);
752 return;
753 }
754 object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
755}
756
757camera_memory_t* CameraHardwareInterface::sGetMemory(
758 int fd, size_t buf_size, uint_t num_bufs,
759 void *user __attribute__((unused)))
760{
761 CameraHeapMemory *mem;
762 if (fd < 0) {
763 mem = new CameraHeapMemory(buf_size, num_bufs);
764 } else {
765 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
766 }
767 mem->incStrong(mem);
768 return &mem->handle;
769}
770
771void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
772{
773 if (!data) {
774 return;
775 }
776
777 CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
778 mem->decStrong(mem);
779}
780
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800781}; // namespace android