blob: 8f534587565f08a2ee1617bf7968f6f3ffbe9114 [file] [log] [blame]
Emilian Peev538c90e2018-12-17 18:03:19 +00001/*
2 * Copyright (C) 2018 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 "Camera3-CompositeStream"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
23
24#include "common/CameraDeviceBase.h"
25#include "CameraDeviceClient.h"
26#include "CompositeStream.h"
27
28namespace android {
29namespace camera3 {
30
Shuzhen Wange8675782019-12-05 09:12:14 -080031CompositeStream::CompositeStream(sp<CameraDeviceBase> device,
Emilian Peev538c90e2018-12-17 18:03:19 +000032 wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
33 mDevice(device),
34 mRemoteCallback(cb),
35 mNumPartialResults(1),
36 mErrorState(false) {
Shuzhen Wange8675782019-12-05 09:12:14 -080037 if (device != nullptr) {
38 CameraMetadata staticInfo = device->info();
Emilian Peev538c90e2018-12-17 18:03:19 +000039 camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
40 if (entry.count > 0) {
41 mNumPartialResults = entry.data.i32[0];
42 }
Shuzhen Wange8675782019-12-05 09:12:14 -080043 mStatusTracker = device->getStatusTracker();
Emilian Peev538c90e2018-12-17 18:03:19 +000044 }
45}
46
47status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
48 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
Austin Borger1c1bee02023-06-01 16:51:35 -070049 camera_stream_rotation_t rotation, int * id, const std::string& physicalCameraId,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080050 const std::unordered_set<int32_t> &sensorPixelModesUsed,
51 std::vector<int> * surfaceIds,
Emilian Peev434248e2022-10-06 14:58:54 -070052 int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
Shuzhen Wangbce53db2022-12-03 00:38:20 +000053 int64_t dynamicProfile, int64_t streamUseCase, bool useReadoutTimestamp) {
Emilian Peev538c90e2018-12-17 18:03:19 +000054 if (hasDeferredConsumer) {
55 ALOGE("%s: Deferred consumers not supported in case of composite streams!",
56 __FUNCTION__);
57 return BAD_VALUE;
58 }
59
60 if (streamSetId != camera3::CAMERA3_STREAM_ID_INVALID) {
61 ALOGE("%s: Surface groups not supported in case of composite streams!",
62 __FUNCTION__);
63 return BAD_VALUE;
64 }
65
66 if (isShared) {
67 ALOGE("%s: Shared surfaces not supported in case of composite streams!",
68 __FUNCTION__);
69 return BAD_VALUE;
70 }
71
Shuzhen Wang83bff122020-11-20 15:51:39 -080072 if (isMultiResolution) {
73 ALOGE("%s: Multi-resolution output not supported in case of composite streams!",
74 __FUNCTION__);
75 return BAD_VALUE;
76 }
77
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080078 return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation,
Emilian Peev434248e2022-10-06 14:58:54 -070079 id, physicalCameraId, sensorPixelModesUsed, surfaceIds, streamSetId, isShared,
Shuzhen Wangbce53db2022-12-03 00:38:20 +000080 colorSpace, dynamicProfile, streamUseCase, useReadoutTimestamp);
Emilian Peev538c90e2018-12-17 18:03:19 +000081}
82
83status_t CompositeStream::deleteStream() {
84 {
85 Mutex::Autolock l(mMutex);
86 mPendingCaptureResults.clear();
87 mCaptureResults.clear();
88 mFrameNumberMap.clear();
89 mErrorFrameNumbers.clear();
Emilian Peev567c31c2023-03-06 15:02:37 -080090 mRequestTimeMap.clear();
Emilian Peev538c90e2018-12-17 18:03:19 +000091 }
92
93 return deleteInternalStreams();
94}
95
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080096void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
97 const CameraMetadata& /*settings*/) {
Emilian Peev538c90e2018-12-17 18:03:19 +000098 Mutex::Autolock l(mMutex);
99 if (!mErrorState && (streamId == getStreamId())) {
100 mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
Emilian Peev567c31c2023-03-06 15:02:37 -0800101 auto ts = systemTime();
102 mRequestTimeMap.emplace(frameNumber, ts);
Emilian Peev538c90e2018-12-17 18:03:19 +0000103 }
104}
105
106void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
107 Mutex::Autolock l(mMutex);
108 if (!mErrorState && !bufferInfo.mError) {
109 mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
110 mInputReadyCondition.signal();
111 }
112}
113
114void CompositeStream::eraseResult(int64_t frameNumber) {
115 Mutex::Autolock l(mMutex);
116
Emilian Peev567c31c2023-03-06 15:02:37 -0800117 auto requestTimeIt = mRequestTimeMap.find(frameNumber);
118 if (requestTimeIt != mRequestTimeMap.end()) {
119 mRequestTimeMap.erase(requestTimeIt);
120 }
121
Emilian Peev538c90e2018-12-17 18:03:19 +0000122 auto it = mPendingCaptureResults.find(frameNumber);
123 if (it == mPendingCaptureResults.end()) {
124 return;
125 }
126
127 it = mPendingCaptureResults.erase(it);
128}
129
130void CompositeStream::onResultAvailable(const CaptureResult& result) {
131 bool resultError = false;
132 {
133 Mutex::Autolock l(mMutex);
134
135 uint64_t frameNumber = result.mResultExtras.frameNumber;
136 bool resultReady = false;
137 auto it = mPendingCaptureResults.find(frameNumber);
138 if (it != mPendingCaptureResults.end()) {
139 it->second.append(result.mMetadata);
140 if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
141 auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
142 if (entry.count == 1) {
143 auto ts = entry.data.i64[0];
144 mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
145 resultReady = true;
146 } else {
147 ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
148 __FUNCTION__, frameNumber);
149 resultError = true;
150 }
151 mPendingCaptureResults.erase(it);
152 }
153 }
154
155 if (resultReady) {
156 mInputReadyCondition.signal();
157 }
158 }
159
160 if (resultError) {
161 onResultError(result.mResultExtras);
162 }
163}
164
165void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
166 Mutex::Autolock l(mMutex);
167 mErrorFrameNumbers.emplace(frameNumber);
168 mInputReadyCondition.signal();
169}
170
171status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
172 sp<CameraDeviceBase> device = mDevice.promote();
173 if (device.get() == nullptr) {
174 return NO_INIT;
175 }
176
177 auto ret = device->addBufferListenerForStream(streamId, this);
178 if (ret != OK) {
179 ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
180 }
181
182 return ret;
183}
184
185bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
186 auto ret = false;
187 switch (errorCode) {
188 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
189 onResultError(resultExtras);
190 break;
191 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
192 ret = onStreamBufferError(resultExtras);
193 break;
194 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
Shuzhen Wange8675782019-12-05 09:12:14 -0800195 onRequestError(resultExtras);
Emilian Peev538c90e2018-12-17 18:03:19 +0000196 break;
197 default:
198 ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
199 Mutex::Autolock l(mMutex);
200 mErrorState = true;
201 break;
202 }
203
204 return ret;
205}
206
Shuzhen Wange8675782019-12-05 09:12:14 -0800207void CompositeStream::notifyError(int64_t frameNumber, int32_t requestId) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000208 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
209 mRemoteCallback.promote();
210
211 if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
212 CaptureResultExtras extras;
213 extras.errorStreamId = getStreamId();
214 extras.frameNumber = frameNumber;
Shuzhen Wange8675782019-12-05 09:12:14 -0800215 extras.requestId = requestId;
Emilian Peev538c90e2018-12-17 18:03:19 +0000216 remoteCb->onDeviceError(
217 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
218 extras);
219 }
220}
221
Emilian Peevc0fe54c2020-03-11 14:05:07 -0700222void CompositeStream::switchToOffline() {
223 Mutex::Autolock l(mMutex);
224 mDevice.clear();
225}
226
Emilian Peev538c90e2018-12-17 18:03:19 +0000227}; // namespace camera3
228}; // namespace android