blob: f539ac150ee331cb91642818f4788f90d28acebe [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 }
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700100 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800101 mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
102 return memPoolId;
103}
104
105hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700106 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800107 if (mHidlMemPoolMap.count(memId) == 0) {
108 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
109 return hardware::Void();
110 }
111 camera_memory_t* mem = mHidlMemPoolMap.at(memId);
112 sPutMemory(mem);
113 mHidlMemPoolMap.erase(memId);
114 return hardware::Void();
115}
116
117hardware::Return<void> CameraHardwareInterface::dataCallback(
118 DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
119 const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700120 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800121 if (mHidlMemPoolMap.count(data) == 0) {
122 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
123 return hardware::Void();
124 }
125 camera_frame_metadata_t md;
126 md.number_of_faces = metadata.faces.size();
127 md.faces = (camera_face_t*) metadata.faces.data();
128 sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
129 return hardware::Void();
130}
131
132hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
133 DataCallbackMsg msgType, uint32_t data,
134 uint32_t bufferIndex, int64_t timestamp) {
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700135 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800136 if (mHidlMemPoolMap.count(data) == 0) {
137 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
138 return hardware::Void();
139 }
140 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
141 return hardware::Void();
142}
143
144hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
145 DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
146 uint32_t bufferIndex, int64_t timestamp) {
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700147 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800148 if (mHidlMemPoolMap.count(data) == 0) {
149 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
150 return hardware::Void();
151 }
152 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
153 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
154 mem->mBuffers[bufferIndex]->pointer();
155 md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
156 sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
157 return hardware::Void();
158}
159
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700160hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
161 DataCallbackMsg msgType,
162 const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
163 std::vector<android::HandleTimestampMessage> msgs;
164 msgs.reserve(messages.size());
165
Yin-Chia Yehc3424df2017-09-07 16:30:46 -0700166 std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700167 for (const auto& hidl_msg : messages) {
168 if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
169 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
170 return hardware::Void();
171 }
172 sp<CameraHeapMemory> mem(
173 static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
174
175 if (hidl_msg.bufferIndex >= mem->mNumBufs) {
176 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
177 hidl_msg.bufferIndex, mem->mNumBufs);
178 return hardware::Void();
179 }
180 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
181 mem->mBuffers[hidl_msg.bufferIndex]->pointer();
182 md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
183
184 msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
185 }
186
187 mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
188 return hardware::Void();
189}
190
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800191std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
192 ANativeWindowBuffer* anb) {
193 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
194
195 buffer_handle_t& buf = anb->handle;
196 auto it = mBufferIdMap.find(buf);
197 if (it == mBufferIdMap.end()) {
198 uint64_t bufId = mNextBufferId++;
199 mBufferIdMap[buf] = bufId;
200 mReversedBufMap[bufId] = anb;
201 return std::make_pair(true, bufId);
202 } else {
203 return std::make_pair(false, it->second);
204 }
205}
206
207void CameraHardwareInterface::cleanupCirculatingBuffers() {
208 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
209 mBufferIdMap.clear();
210 mReversedBufMap.clear();
211}
212
213hardware::Return<void>
214CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
215 ANativeWindow *a = mPreviewWindow.get();
216 if (a == nullptr) {
217 ALOGE("%s: preview window is null", __FUNCTION__);
218 return hardware::Void();
219 }
220 ANativeWindowBuffer* anb;
221 int rc = native_window_dequeue_buffer_and_wait(a, &anb);
222 Status s = Status::INTERNAL_ERROR;
223 uint64_t bufferId = 0;
224 uint32_t stride = 0;
225 hidl_handle buf = nullptr;
226 if (rc == OK) {
227 s = Status::OK;
228 auto pair = getBufferId(anb);
229 buf = (pair.first) ? anb->handle : nullptr;
230 bufferId = pair.second;
231 stride = anb->stride;
232 }
233
234 _hidl_cb(s, bufferId, buf, stride);
235 return hardware::Void();
236}
237
238hardware::Return<Status>
239CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
240 ANativeWindow *a = mPreviewWindow.get();
241 if (a == nullptr) {
242 ALOGE("%s: preview window is null", __FUNCTION__);
243 return Status::INTERNAL_ERROR;
244 }
245 if (mReversedBufMap.count(bufferId) == 0) {
246 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
247 return Status::ILLEGAL_ARGUMENT;
248 }
249 int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
250 if (rc == 0) {
251 return Status::OK;
252 }
253 return Status::INTERNAL_ERROR;
254}
255
256hardware::Return<Status>
257CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
258 ANativeWindow *a = mPreviewWindow.get();
259 if (a == nullptr) {
260 ALOGE("%s: preview window is null", __FUNCTION__);
261 return Status::INTERNAL_ERROR;
262 }
263 if (mReversedBufMap.count(bufferId) == 0) {
264 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
265 return Status::ILLEGAL_ARGUMENT;
266 }
267 int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
268 if (rc == 0) {
269 return Status::OK;
270 }
271 return Status::INTERNAL_ERROR;
272}
273
274hardware::Return<Status>
275CameraHardwareInterface::setBufferCount(uint32_t count) {
276 ANativeWindow *a = mPreviewWindow.get();
277 if (a != nullptr) {
278 // Workaround for b/27039775
279 // Previously, setting the buffer count would reset the buffer
280 // queue's flag that allows for all buffers to be dequeued on the
281 // producer side, instead of just the producer's declared max count,
282 // if no filled buffers have yet been queued by the producer. This
283 // reset no longer happens, but some HALs depend on this behavior,
284 // so it needs to be maintained for HAL backwards compatibility.
285 // Simulate the prior behavior by disconnecting/reconnecting to the
286 // window and setting the values again. This has the drawback of
287 // actually causing memory reallocation, which may not have happened
288 // in the past.
289 native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
290 native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
291 if (mPreviewScalingMode != NOT_SET) {
292 native_window_set_scaling_mode(a, mPreviewScalingMode);
293 }
294 if (mPreviewTransform != NOT_SET) {
295 native_window_set_buffers_transform(a, mPreviewTransform);
296 }
297 if (mPreviewWidth != NOT_SET) {
298 native_window_set_buffers_dimensions(a,
299 mPreviewWidth, mPreviewHeight);
300 native_window_set_buffers_format(a, mPreviewFormat);
301 }
302 if (mPreviewUsage != 0) {
303 native_window_set_usage(a, mPreviewUsage);
304 }
305 if (mPreviewSwapInterval != NOT_SET) {
306 a->setSwapInterval(a, mPreviewSwapInterval);
307 }
308 if (mPreviewCrop.left != NOT_SET) {
309 native_window_set_crop(a, &(mPreviewCrop));
310 }
311 }
312 int rc = native_window_set_buffer_count(a, count);
313 if (rc == OK) {
314 cleanupCirculatingBuffers();
315 return Status::OK;
316 }
317 return Status::INTERNAL_ERROR;
318}
319
320hardware::Return<Status>
321CameraHardwareInterface::setBuffersGeometry(
322 uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
323 Status s = Status::INTERNAL_ERROR;
324 ANativeWindow *a = mPreviewWindow.get();
325 if (a == nullptr) {
326 ALOGE("%s: preview window is null", __FUNCTION__);
327 return s;
328 }
329 mPreviewWidth = w;
330 mPreviewHeight = h;
331 mPreviewFormat = (int) format;
332 int rc = native_window_set_buffers_dimensions(a, w, h);
333 if (rc == OK) {
334 rc = native_window_set_buffers_format(a, mPreviewFormat);
335 }
336 if (rc == OK) {
337 cleanupCirculatingBuffers();
338 s = Status::OK;
339 }
340 return s;
341}
342
343hardware::Return<Status>
344CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
345 Status s = Status::INTERNAL_ERROR;
346 ANativeWindow *a = mPreviewWindow.get();
347 if (a == nullptr) {
348 ALOGE("%s: preview window is null", __FUNCTION__);
349 return s;
350 }
351 mPreviewCrop.left = left;
352 mPreviewCrop.top = top;
353 mPreviewCrop.right = right;
354 mPreviewCrop.bottom = bottom;
355 int rc = native_window_set_crop(a, &mPreviewCrop);
356 if (rc == OK) {
357 s = Status::OK;
358 }
359 return s;
360}
361
362hardware::Return<Status>
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700363CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800364 Status s = Status::INTERNAL_ERROR;
365 ANativeWindow *a = mPreviewWindow.get();
366 if (a == nullptr) {
367 ALOGE("%s: preview window is null", __FUNCTION__);
368 return s;
369 }
Emilian Peev050f5dc2017-05-18 14:43:56 +0100370 mPreviewUsage = static_cast<uint64_t> (usage);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800371 int rc = native_window_set_usage(a, mPreviewUsage);
372 if (rc == OK) {
373 cleanupCirculatingBuffers();
374 s = Status::OK;
375 }
376 return s;
377}
378
379hardware::Return<Status>
380CameraHardwareInterface::setSwapInterval(int32_t interval) {
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 mPreviewSwapInterval = interval;
388 int rc = a->setSwapInterval(a, interval);
389 if (rc == OK) {
390 s = Status::OK;
391 }
392 return s;
393}
394
395hardware::Return<void>
396CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
397 ANativeWindow *a = mPreviewWindow.get();
398 if (a == nullptr) {
399 ALOGE("%s: preview window is null", __FUNCTION__);
400 return hardware::Void();
401 }
402 int count = 0;
403 int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
404 Status s = Status::INTERNAL_ERROR;
405 if (rc == OK) {
406 s = Status::OK;
407 }
408 _hidl_cb(s, count);
409 return hardware::Void();
410}
411
412hardware::Return<Status>
413CameraHardwareInterface::setTimestamp(int64_t timestamp) {
414 Status s = Status::INTERNAL_ERROR;
415 ANativeWindow *a = mPreviewWindow.get();
416 if (a == nullptr) {
417 ALOGE("%s: preview window is null", __FUNCTION__);
418 return s;
419 }
420 int rc = native_window_set_buffers_timestamp(a, timestamp);
421 if (rc == OK) {
422 s = Status::OK;
423 }
424 return s;
425}
426
427status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
428{
429 ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
430 if (CC_LIKELY(mHidlDevice != nullptr)) {
431 mPreviewWindow = buf;
432 if (buf != nullptr) {
433 if (mPreviewScalingMode != NOT_SET) {
434 setPreviewScalingMode(mPreviewScalingMode);
435 }
436 if (mPreviewTransform != NOT_SET) {
437 setPreviewTransform(mPreviewTransform);
438 }
439 }
440 return CameraProviderManager::mapToStatusT(
441 mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800442 }
443 return INVALID_OPERATION;
444}
445
446void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
447 data_callback data_cb,
448 data_callback_timestamp data_cb_timestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700449 data_callback_timestamp_batch data_cb_timestamp_batch,
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800450 void* user)
451{
452 mNotifyCb = notify_cb;
453 mDataCb = data_cb;
454 mDataCbTimestamp = data_cb_timestamp;
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700455 mDataCbTimestampBatch = data_cb_timestamp_batch;
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800456 mCbUser = user;
457
458 ALOGV("%s(%s)", __FUNCTION__, mName.string());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800459}
460
461void CameraHardwareInterface::enableMsgType(int32_t msgType)
462{
463 ALOGV("%s(%s)", __FUNCTION__, mName.string());
464 if (CC_LIKELY(mHidlDevice != nullptr)) {
465 mHidlDevice->enableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800466 }
467}
468
469void CameraHardwareInterface::disableMsgType(int32_t msgType)
470{
471 ALOGV("%s(%s)", __FUNCTION__, mName.string());
472 if (CC_LIKELY(mHidlDevice != nullptr)) {
473 mHidlDevice->disableMsgType(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800474 }
475}
476
477int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
478{
479 ALOGV("%s(%s)", __FUNCTION__, mName.string());
480 if (CC_LIKELY(mHidlDevice != nullptr)) {
481 return mHidlDevice->msgTypeEnabled(msgType);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800482 }
483 return false;
484}
485
486status_t CameraHardwareInterface::startPreview()
487{
488 ALOGV("%s(%s)", __FUNCTION__, mName.string());
489 if (CC_LIKELY(mHidlDevice != nullptr)) {
490 return CameraProviderManager::mapToStatusT(
491 mHidlDevice->startPreview());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800492 }
493 return INVALID_OPERATION;
494}
495
496void CameraHardwareInterface::stopPreview()
497{
498 ALOGV("%s(%s)", __FUNCTION__, mName.string());
499 if (CC_LIKELY(mHidlDevice != nullptr)) {
500 mHidlDevice->stopPreview();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800501 }
502}
503
504int CameraHardwareInterface::previewEnabled()
505{
506 ALOGV("%s(%s)", __FUNCTION__, mName.string());
507 if (CC_LIKELY(mHidlDevice != nullptr)) {
508 return mHidlDevice->previewEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800509 }
510 return false;
511}
512
513status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
514{
515 ALOGV("%s(%s)", __FUNCTION__, mName.string());
516 if (CC_LIKELY(mHidlDevice != nullptr)) {
517 return CameraProviderManager::mapToStatusT(
518 mHidlDevice->storeMetaDataInBuffers(enable));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800519 }
520 return enable ? INVALID_OPERATION: OK;
521}
522
523status_t CameraHardwareInterface::startRecording()
524{
525 ALOGV("%s(%s)", __FUNCTION__, mName.string());
526 if (CC_LIKELY(mHidlDevice != nullptr)) {
527 return CameraProviderManager::mapToStatusT(
528 mHidlDevice->startRecording());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800529 }
530 return INVALID_OPERATION;
531}
532
533/**
534 * Stop a previously started recording.
535 */
536void CameraHardwareInterface::stopRecording()
537{
538 ALOGV("%s(%s)", __FUNCTION__, mName.string());
539 if (CC_LIKELY(mHidlDevice != nullptr)) {
540 mHidlDevice->stopRecording();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800541 }
542}
543
544/**
545 * Returns true if recording is enabled.
546 */
547int CameraHardwareInterface::recordingEnabled()
548{
549 ALOGV("%s(%s)", __FUNCTION__, mName.string());
550 if (CC_LIKELY(mHidlDevice != nullptr)) {
551 return mHidlDevice->recordingEnabled();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800552 }
553 return false;
554}
555
556void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
557{
558 ALOGV("%s(%s)", __FUNCTION__, mName.string());
559 ssize_t offset;
560 size_t size;
561 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
562 int heapId = heap->getHeapID();
563 int bufferIndex = offset / size;
564 if (CC_LIKELY(mHidlDevice != nullptr)) {
565 if (size == sizeof(VideoNativeHandleMetadata)) {
566 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
567 // Caching the handle here because md->pHandle will be subject to HAL's edit
568 native_handle_t* nh = md->pHandle;
569 hidl_handle frame = nh;
570 mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
571 native_handle_close(nh);
572 native_handle_delete(nh);
573 } else {
574 mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
575 }
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800576 }
577}
578
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700579void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
580{
581 ALOGV("%s(%s)", __FUNCTION__, mName.string());
582 size_t n = frames.size();
583 std::vector<VideoFrameMessage> msgs;
584 msgs.reserve(n);
585 for (auto& mem : frames) {
586 if (CC_LIKELY(mHidlDevice != nullptr)) {
587 ssize_t offset;
588 size_t size;
589 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
590 if (size == sizeof(VideoNativeHandleMetadata)) {
591 uint32_t heapId = heap->getHeapID();
592 uint32_t bufferIndex = offset / size;
593 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
594 // Caching the handle here because md->pHandle will be subject to HAL's edit
595 native_handle_t* nh = md->pHandle;
596 VideoFrameMessage msg;
597 msgs.push_back({nh, heapId, bufferIndex});
598 } else {
599 ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
600 return;
601 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700602 }
603 }
604
605 mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
606
607 for (auto& msg : msgs) {
608 native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
609 native_handle_close(nh);
610 native_handle_delete(nh);
611 }
612}
613
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800614status_t CameraHardwareInterface::autoFocus()
615{
616 ALOGV("%s(%s)", __FUNCTION__, mName.string());
617 if (CC_LIKELY(mHidlDevice != nullptr)) {
618 return CameraProviderManager::mapToStatusT(
619 mHidlDevice->autoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800620 }
621 return INVALID_OPERATION;
622}
623
624status_t CameraHardwareInterface::cancelAutoFocus()
625{
626 ALOGV("%s(%s)", __FUNCTION__, mName.string());
627 if (CC_LIKELY(mHidlDevice != nullptr)) {
628 return CameraProviderManager::mapToStatusT(
629 mHidlDevice->cancelAutoFocus());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800630 }
631 return INVALID_OPERATION;
632}
633
634status_t CameraHardwareInterface::takePicture()
635{
636 ALOGV("%s(%s)", __FUNCTION__, mName.string());
637 if (CC_LIKELY(mHidlDevice != nullptr)) {
638 return CameraProviderManager::mapToStatusT(
639 mHidlDevice->takePicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800640 }
641 return INVALID_OPERATION;
642}
643
644status_t CameraHardwareInterface::cancelPicture()
645{
646 ALOGV("%s(%s)", __FUNCTION__, mName.string());
647 if (CC_LIKELY(mHidlDevice != nullptr)) {
648 return CameraProviderManager::mapToStatusT(
649 mHidlDevice->cancelPicture());
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800650 }
651 return INVALID_OPERATION;
652}
653
654status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
655{
656 ALOGV("%s(%s)", __FUNCTION__, mName.string());
657 if (CC_LIKELY(mHidlDevice != nullptr)) {
658 return CameraProviderManager::mapToStatusT(
659 mHidlDevice->setParameters(params.flatten().string()));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800660 }
661 return INVALID_OPERATION;
662}
663
664CameraParameters CameraHardwareInterface::getParameters() const
665{
666 ALOGV("%s(%s)", __FUNCTION__, mName.string());
667 CameraParameters parms;
668 if (CC_LIKELY(mHidlDevice != nullptr)) {
669 hardware::hidl_string outParam;
670 mHidlDevice->getParameters(
671 [&outParam](const auto& outStr) {
672 outParam = outStr;
673 });
674 String8 tmp(outParam.c_str());
675 parms.unflatten(tmp);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800676 }
677 return parms;
678}
679
680status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
681{
682 ALOGV("%s(%s)", __FUNCTION__, mName.string());
683 if (CC_LIKELY(mHidlDevice != nullptr)) {
684 return CameraProviderManager::mapToStatusT(
685 mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800686 }
687 return INVALID_OPERATION;
688}
689
690/**
691 * Release the hardware resources owned by this object. Note that this is
692 * *not* done in the destructor.
693 */
694void CameraHardwareInterface::release() {
695 ALOGV("%s(%s)", __FUNCTION__, mName.string());
696 if (CC_LIKELY(mHidlDevice != nullptr)) {
697 mHidlDevice->close();
698 mHidlDevice.clear();
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800699 }
700}
701
702/**
703 * Dump state of the camera hardware
704 */
705status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
706{
707 ALOGV("%s(%s)", __FUNCTION__, mName.string());
708 if (CC_LIKELY(mHidlDevice != nullptr)) {
709 native_handle_t* handle = native_handle_create(1,0);
710 handle->data[0] = fd;
711 Status s = mHidlDevice->dumpState(handle);
712 native_handle_delete(handle);
713 return CameraProviderManager::mapToStatusT(s);
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800714 }
715 return OK; // It's fine if the HAL doesn't implement dump()
716}
717
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800718void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
719 int32_t ext2, void *user)
720{
721 ALOGV("%s", __FUNCTION__);
722 CameraHardwareInterface *object =
723 static_cast<CameraHardwareInterface *>(user);
724 object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
725}
726
727void CameraHardwareInterface::sDataCb(int32_t msg_type,
728 const camera_memory_t *data, unsigned int index,
729 camera_frame_metadata_t *metadata,
730 void *user)
731{
732 ALOGV("%s", __FUNCTION__);
733 CameraHardwareInterface *object =
734 static_cast<CameraHardwareInterface *>(user);
735 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
736 if (index >= mem->mNumBufs) {
737 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
738 index, mem->mNumBufs);
739 return;
740 }
741 object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
742}
743
744void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
745 const camera_memory_t *data, unsigned index,
746 void *user)
747{
748 ALOGV("%s", __FUNCTION__);
749 CameraHardwareInterface *object =
750 static_cast<CameraHardwareInterface *>(user);
751 // Start refcounting the heap object from here on. When the clients
752 // drop all references, it will be destroyed (as well as the enclosed
753 // MemoryHeapBase.
754 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
755 if (index >= mem->mNumBufs) {
756 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
757 index, mem->mNumBufs);
758 return;
759 }
760 object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
761}
762
763camera_memory_t* CameraHardwareInterface::sGetMemory(
764 int fd, size_t buf_size, uint_t num_bufs,
765 void *user __attribute__((unused)))
766{
767 CameraHeapMemory *mem;
768 if (fd < 0) {
769 mem = new CameraHeapMemory(buf_size, num_bufs);
770 } else {
771 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
772 }
773 mem->incStrong(mem);
774 return &mem->handle;
775}
776
777void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
778{
779 if (!data) {
780 return;
781 }
782
783 CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
784 mem->decStrong(mem);
785}
786
Yin-Chia Yeh4717c472017-02-13 10:56:40 -0800787}; // namespace android