blob: ae5d57638012492aecbb7099b0ebb0a09e183231 [file] [log] [blame]
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CamDevSession@3.2-impl"
18#include <android/log.h>
19
20#include <utils/Trace.h>
21#include <hardware/gralloc.h>
22#include <hardware/gralloc1.h>
23#include "CameraDeviceSession.h"
24
25namespace android {
26namespace hardware {
27namespace camera {
28namespace device {
29namespace V3_2 {
30namespace implementation {
31
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080032HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070033
34CameraDeviceSession::CameraDeviceSession(
35 camera3_device_t* device, const sp<ICameraDeviceCallback>& callback) :
36 camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
37 mDevice(device),
38 mCallback(callback) {
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -070039 mInitFail = initialize();
40}
41
42bool CameraDeviceSession::initialize() {
43 /** Initialize device with callback functions */
44 ATRACE_BEGIN("camera3->initialize");
45 status_t res = mDevice->ops->initialize(mDevice, this);
46 ATRACE_END();
47
48 if (res != OK) {
49 ALOGE("%s: Unable to initialize HAL device: %s (%d)",
50 __FUNCTION__, strerror(-res), res);
51 mDevice->common.close(&mDevice->common);
52 mClosed = true;
53 return true;
54 }
55 return false;
56}
57
58CameraDeviceSession::~CameraDeviceSession() {
59 if (!isClosed()) {
60 ALOGE("CameraDeviceSession deleted before close!");
61 close();
62 }
63}
64
65bool CameraDeviceSession::isClosed() {
66 Mutex::Autolock _l(mStateLock);
67 return mClosed;
68}
69
70Status CameraDeviceSession::initStatus() const {
71 Mutex::Autolock _l(mStateLock);
72 Status status = Status::OK;
73 if (mInitFail) {
74 status = Status::INTERNAL_ERROR;
75 } else if (mDisconnected) {
76 status = Status::CAMERA_DISCONNECTED;
77 } else if (mClosed) {
78 status = Status::INTERNAL_ERROR;
79 }
80 return status;
81}
82
83void CameraDeviceSession::disconnect() {
84 Mutex::Autolock _l(mStateLock);
85 mDisconnected = true;
86 ALOGW("%s: Camera device is disconnected. Closing.", __FUNCTION__);
87 if (!mClosed) {
88 mDevice->common.close(&mDevice->common);
89 mClosed = true;
90 }
91}
92
93void CameraDeviceSession::dumpState(const native_handle_t* fd) {
94 if (!isClosed()) {
95 mDevice->ops->dump(mDevice, fd->data[0]);
96 }
97}
98
99Status CameraDeviceSession::importRequest(
100 const CaptureRequest& request,
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800101 hidl_vec<buffer_handle_t*>& allBufPtrs,
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700102 hidl_vec<int>& allFences) {
103 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800104 request.inputBuffer.bufferId != 0);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700105 size_t numOutputBufs = request.outputBuffers.size();
106 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
107 // Validate all I/O buffers
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800108 hidl_vec<buffer_handle_t> allBufs;
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800109 hidl_vec<uint64_t> allBufIds;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700110 allBufs.resize(numBufs);
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800111 allBufIds.resize(numBufs);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800112 allBufPtrs.resize(numBufs);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700113 allFences.resize(numBufs);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800114 std::vector<int32_t> streamIds(numBufs);
115
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700116 for (size_t i = 0; i < numOutputBufs; i++) {
117 allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800118 allBufIds[i] = request.outputBuffers[i].bufferId;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800119 allBufPtrs[i] = &allBufs[i];
120 streamIds[i] = request.outputBuffers[i].streamId;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700121 }
122 if (hasInputBuf) {
123 allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800124 allBufIds[numOutputBufs] = request.inputBuffer.bufferId;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800125 allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs];
126 streamIds[numOutputBufs] = request.inputBuffer.streamId;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700127 }
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800128
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700129 for (size_t i = 0; i < numBufs; i++) {
130 buffer_handle_t buf = allBufs[i];
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800131 uint64_t bufId = allBufIds[i];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800132 CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]];
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800133 if (cbs.count(bufId) == 0) {
134 if (buf == nullptr) {
135 ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
136 return Status::ILLEGAL_ARGUMENT;
137 }
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800138 // Register a newly seen buffer
139 buffer_handle_t importedBuf = buf;
140 sHandleImporter.importBuffer(importedBuf);
141 if (importedBuf == nullptr) {
142 ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
143 return Status::INTERNAL_ERROR;
144 } else {
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800145 cbs[bufId] = importedBuf;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800146 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700147 }
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800148 allBufPtrs[i] = &cbs[bufId];
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700149 }
150
151 // All buffers are imported. Now validate output buffer acquire fences
152 for (size_t i = 0; i < numOutputBufs; i++) {
153 if (!sHandleImporter.importFence(
154 request.outputBuffers[i].acquireFence, allFences[i])) {
155 ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800156 cleanupInflightFences(allFences, i);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700157 return Status::INTERNAL_ERROR;
158 }
159 }
160
161 // Validate input buffer acquire fences
162 if (hasInputBuf) {
163 if (!sHandleImporter.importFence(
164 request.inputBuffer.acquireFence, allFences[numOutputBufs])) {
165 ALOGE("%s: input buffer acquire fence is invalid", __FUNCTION__);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800166 cleanupInflightFences(allFences, numOutputBufs);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700167 return Status::INTERNAL_ERROR;
168 }
169 }
170 return Status::OK;
171}
172
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800173void CameraDeviceSession::cleanupInflightFences(
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700174 hidl_vec<int>& allFences, size_t numFences) {
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700175 for (size_t j = 0; j < numFences; j++) {
176 sHandleImporter.closeFence(allFences[j]);
177 }
178}
179
180// Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
181Return<void> CameraDeviceSession::constructDefaultRequestSettings(
182 RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) {
183 Status status = initStatus();
184 CameraMetadata outMetadata;
185 const camera_metadata_t *rawRequest;
186 if (status == Status::OK) {
187 ATRACE_BEGIN("camera3->construct_default_request_settings");
188 rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
189 ATRACE_END();
190 if (rawRequest == nullptr) {
191 ALOGI("%s: template %d is not supported on this camera device",
192 __FUNCTION__, type);
193 status = Status::ILLEGAL_ARGUMENT;
194 } else {
195 convertToHidl(rawRequest, &outMetadata);
196 }
197 }
198 _hidl_cb(status, outMetadata);
199 return Void();
200}
201
202Return<void> CameraDeviceSession::configureStreams(
203 const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) {
204 Status status = initStatus();
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800205 HalStreamConfiguration outStreams;
206
207 // hold the inflight lock for entire configureStreams scope since there must not be any
208 // inflight request/results during stream configuration.
209 Mutex::Autolock _l(mInflightLock);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700210 if (!mInflightBuffers.empty()) {
211 ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
212 __FUNCTION__, mInflightBuffers.size());
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800213 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
214 return Void();
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700215 }
216
Emilian Peev98014ff2017-02-02 16:20:12 +0000217 if (status != Status::OK) {
218 _hidl_cb(status, outStreams);
219 return Void();
220 }
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800221
Emilian Peev98014ff2017-02-02 16:20:12 +0000222 camera3_stream_configuration_t stream_list;
223 hidl_vec<camera3_stream_t*> streams;
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800224
Emilian Peev98014ff2017-02-02 16:20:12 +0000225 stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode;
226 stream_list.num_streams = requestedConfiguration.streams.size();
227 streams.resize(stream_list.num_streams);
228 stream_list.streams = streams.data();
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700229
Emilian Peev98014ff2017-02-02 16:20:12 +0000230 for (uint32_t i = 0; i < stream_list.num_streams; i++) {
231 int id = requestedConfiguration.streams[i].id;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700232
Emilian Peev98014ff2017-02-02 16:20:12 +0000233 if (mStreamMap.count(id) == 0) {
234 Camera3Stream stream;
235 convertFromHidl(requestedConfiguration.streams[i], &stream);
236 mStreamMap[id] = stream;
237 mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
238 } else {
239 // width/height/format must not change, but usage/rotation might need to change
240 if (mStreamMap[id].stream_type !=
241 (int) requestedConfiguration.streams[i].streamType ||
242 mStreamMap[id].width != requestedConfiguration.streams[i].width ||
243 mStreamMap[id].height != requestedConfiguration.streams[i].height ||
244 mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
245 mStreamMap[id].data_space != (android_dataspace_t)
246 requestedConfiguration.streams[i].dataSpace) {
247 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
248 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
249 return Void();
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800250 }
Emilian Peev98014ff2017-02-02 16:20:12 +0000251 mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
252 mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700253 }
Emilian Peev98014ff2017-02-02 16:20:12 +0000254 streams[i] = &mStreamMap[id];
255 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700256
Emilian Peev98014ff2017-02-02 16:20:12 +0000257 ATRACE_BEGIN("camera3->configure_streams");
258 status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
259 ATRACE_END();
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700260
Emilian Peev98014ff2017-02-02 16:20:12 +0000261 // In case Hal returns error most likely it was not able to release
262 // the corresponding resources of the deleted streams.
263 if (ret == OK) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800264 // delete unused streams, note we do this after adding new streams to ensure new stream
265 // will not have the same address as deleted stream, and HAL has a chance to reference
266 // the to be deleted stream in configure_streams call
267 for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
268 int id = it->first;
269 bool found = false;
270 for (const auto& stream : requestedConfiguration.streams) {
271 if (id == stream.id) {
272 found = true;
273 break;
274 }
275 }
276 if (!found) {
277 // Unmap all buffers of deleted stream
Emilian Peev98014ff2017-02-02 16:20:12 +0000278 // in case the configuration call succeeds and HAL
279 // is able to release the corresponding resources too.
280 cleanupBuffersLocked(id);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800281 it = mStreamMap.erase(it);
282 } else {
283 ++it;
284 }
285 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700286 }
Emilian Peev98014ff2017-02-02 16:20:12 +0000287
288 if (ret == -EINVAL) {
289 status = Status::ILLEGAL_ARGUMENT;
290 } else if (ret != OK) {
291 status = Status::INTERNAL_ERROR;
292 } else {
293 convertToHidl(stream_list, &outStreams);
294 }
295
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700296 _hidl_cb(status, outStreams);
297 return Void();
298}
299
Emilian Peev98014ff2017-02-02 16:20:12 +0000300// Needs to get called after acquiring 'mInflightLock'
301void CameraDeviceSession::cleanupBuffersLocked(int id) {
302 for (auto& pair : mCirculatingBuffers.at(id)) {
303 sHandleImporter.freeBuffer(pair.second);
304 }
305 mCirculatingBuffers[id].clear();
306 mCirculatingBuffers.erase(id);
307}
308
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700309Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& request) {
310 Status status = initStatus();
311 if (status != Status::OK) {
312 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
313 return status;
314 }
315
316 camera3_capture_request_t halRequest;
317 halRequest.frame_number = request.frameNumber;
318 bool converted = convertFromHidl(request.settings, &halRequest.settings);
319 if (!converted) {
320 ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
321 return Status::INTERNAL_ERROR;
322 }
323
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800324 hidl_vec<buffer_handle_t*> allBufPtrs;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700325 hidl_vec<int> allFences;
326 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
Yin-Chia Yehd926f932017-01-09 15:21:11 -0800327 request.inputBuffer.bufferId != 0);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700328 size_t numOutputBufs = request.outputBuffers.size();
329 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800330 status = importRequest(request, allBufPtrs, allFences);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700331 if (status != Status::OK) {
332 return status;
333 }
334
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700335 hidl_vec<camera3_stream_buffer_t> outHalBufs;
336 outHalBufs.resize(numOutputBufs);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800337 {
338 Mutex::Autolock _l(mInflightLock);
339 if (hasInputBuf) {
340 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
341 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
342 convertFromHidl(
343 allBufPtrs[numOutputBufs], request.inputBuffer.status,
344 &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
345 &bufCache);
346 halRequest.input_buffer = &bufCache;
347 } else {
348 halRequest.input_buffer = nullptr;
349 }
350
351 halRequest.num_output_buffers = numOutputBufs;
352 for (size_t i = 0; i < numOutputBufs; i++) {
353 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
354 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
355 convertFromHidl(
356 allBufPtrs[i], request.outputBuffers[i].status,
357 &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
358 &bufCache);
359 outHalBufs[i] = bufCache;
360 }
361 halRequest.output_buffers = outHalBufs.data();
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700362 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700363
364 ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
365 ATRACE_BEGIN("camera3->process_capture_request");
366 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
367 ATRACE_END();
368 if (ret != OK) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800369 Mutex::Autolock _l(mInflightLock);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700370 ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
371
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800372 cleanupInflightFences(allFences, numBufs);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700373 if (hasInputBuf) {
374 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
375 mInflightBuffers.erase(key);
376 }
377 for (size_t i = 0; i < numOutputBufs; i++) {
378 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
379 mInflightBuffers.erase(key);
380 }
381 return Status::INTERNAL_ERROR;
382 }
383
384 return Status::OK;
385}
386
387Return<Status> CameraDeviceSession::flush() {
388 Status status = initStatus();
389 if (status == Status::OK) {
390 // Flush is always supported on device 3.1 or later
391 status_t ret = mDevice->ops->flush(mDevice);
392 if (ret != OK) {
393 status = Status::INTERNAL_ERROR;
394 }
395 }
396 return status;
397}
398
399Return<void> CameraDeviceSession::close() {
400 Mutex::Autolock _l(mStateLock);
401 if (!mClosed) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800402 {
403 Mutex::Autolock _l(mInflightLock);
404 if (!mInflightBuffers.empty()) {
405 ALOGE("%s: trying to close while there are still %zu inflight buffers!",
406 __FUNCTION__, mInflightBuffers.size());
407 }
408 }
409
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700410 ATRACE_BEGIN("camera3->close");
411 mDevice->common.close(&mDevice->common);
412 ATRACE_END();
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800413
414 // free all imported buffers
415 for(auto& pair : mCirculatingBuffers) {
416 CirculatingBuffers& buffers = pair.second;
417 for (auto& p2 : buffers) {
418 sHandleImporter.freeBuffer(p2.second);
419 }
420 }
421
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700422 mClosed = true;
423 }
424 return Void();
425}
426
427/**
428 * Static callback forwarding methods from HAL to instance
429 */
430void CameraDeviceSession::sProcessCaptureResult(
431 const camera3_callback_ops *cb,
432 const camera3_capture_result *hal_result) {
433 CameraDeviceSession *d =
434 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
435
436 uint32_t frameNumber = hal_result->frame_number;
437 bool hasInputBuf = (hal_result->input_buffer != nullptr);
438 size_t numOutputBufs = hal_result->num_output_buffers;
439 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800440 {
441 Mutex::Autolock _l(d->mInflightLock);
442 if (hasInputBuf) {
443 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
444 // validate if buffer is inflight
445 auto key = std::make_pair(streamId, frameNumber);
446 if (d->mInflightBuffers.count(key) != 1) {
447 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
448 __FUNCTION__, streamId, frameNumber);
449 return;
450 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700451 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700452
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800453 for (size_t i = 0; i < numOutputBufs; i++) {
454 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
455 // validate if buffer is inflight
456 auto key = std::make_pair(streamId, frameNumber);
457 if (d->mInflightBuffers.count(key) != 1) {
458 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
459 __FUNCTION__, streamId, frameNumber);
460 return;
461 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700462 }
463 }
464 // We don't need to validate/import fences here since we will be passing them to camera service
465 // within the scope of this function
466
467 CaptureResult result;
468 hidl_vec<native_handle_t*> releaseFences;
469 releaseFences.resize(numBufs);
470 result.frameNumber = frameNumber;
471 result.partialResult = hal_result->partial_result;
472 convertToHidl(hal_result->result, &result.result);
473 if (hasInputBuf) {
474 result.inputBuffer.streamId =
475 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
476 result.inputBuffer.buffer = nullptr;
477 result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
478 // skip acquire fence since it's no use to camera service
479 if (hal_result->input_buffer->release_fence != -1) {
480 releaseFences[numOutputBufs] = native_handle_create(/*numFds*/1, /*numInts*/0);
481 releaseFences[numOutputBufs]->data[0] = hal_result->input_buffer->release_fence;
482 result.inputBuffer.releaseFence = releaseFences[numOutputBufs];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800483 } else {
484 releaseFences[numOutputBufs] = nullptr;
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700485 }
486 } else {
487 result.inputBuffer.streamId = -1;
488 }
489
490 result.outputBuffers.resize(numOutputBufs);
491 for (size_t i = 0; i < numOutputBufs; i++) {
492 result.outputBuffers[i].streamId =
493 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
494 result.outputBuffers[i].buffer = nullptr;
495 result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
496 // skip acquire fence since it's of no use to camera service
497 if (hal_result->output_buffers[i].release_fence != -1) {
498 releaseFences[i] = native_handle_create(/*numFds*/1, /*numInts*/0);
499 releaseFences[i]->data[0] = hal_result->output_buffers[i].release_fence;
500 result.outputBuffers[i].releaseFence = releaseFences[i];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800501 } else {
502 releaseFences[i] = nullptr;
503 }
504 }
505
506 // Free inflight record/fences.
507 // Do this before call back to camera service because camera service might jump to
508 // configure_streams right after the processCaptureResult call so we need to finish
509 // updating inflight queues first
510 {
511 Mutex::Autolock _l(d->mInflightLock);
512 if (hasInputBuf) {
513 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
514 auto key = std::make_pair(streamId, frameNumber);
Yin-Chia Yeh75846242017-01-09 14:29:06 -0800515 // TODO (b/34169301): currently HAL closed the fence
516 //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800517 d->mInflightBuffers.erase(key);
518 }
519
520 for (size_t i = 0; i < numOutputBufs; i++) {
521 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
522 auto key = std::make_pair(streamId, frameNumber);
Yin-Chia Yeh75846242017-01-09 14:29:06 -0800523 // TODO (b/34169301): currently HAL closed the fence
524 //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800525 d->mInflightBuffers.erase(key);
526 }
527
528 if (d->mInflightBuffers.empty()) {
529 ALOGV("%s: inflight buffer queue is now empty!", __FUNCTION__);
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700530 }
531 }
532
533 d->mCallback->processCaptureResult(result);
534
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700535 for (size_t i = 0; i < releaseFences.size(); i++) {
536 // We don't close the FD here as HAL needs to signal it later.
537 native_handle_delete(releaseFences[i]);
538 }
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700539}
540
541void CameraDeviceSession::sNotify(
542 const camera3_callback_ops *cb,
543 const camera3_notify_msg *msg) {
544 CameraDeviceSession *d =
545 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
546 NotifyMsg hidlMsg;
547 convertToHidl(msg, &hidlMsg);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800548 if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
549 hidlMsg.msg.error.errorStreamId != -1) {
Yin-Chia Yehfaef8f92016-10-31 12:53:56 -0700550 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
551 ALOGE("%s: unknown stream ID %d reports an error!",
552 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
553 }
554 return;
555 }
556 d->mCallback->notify(hidlMsg);
557}
558
559} // namespace implementation
560} // namespace V3_2
561} // namespace device
562} // namespace camera
563} // namespace hardware
564} // namespace android