blob: 515b7f253e083117b4e4d2271e7f2cbd99499b7d [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,
Emilian Peevf4816702020-04-03 15:44:51 -070049 camera_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
Shuzhen Wang83bff122020-11-20 15:51:39 -080050 std::vector<int> * surfaceIds, int streamSetId, bool isShared, bool isMultiResolution) {
Emilian Peev538c90e2018-12-17 18:03:19 +000051 if (hasDeferredConsumer) {
52 ALOGE("%s: Deferred consumers not supported in case of composite streams!",
53 __FUNCTION__);
54 return BAD_VALUE;
55 }
56
57 if (streamSetId != camera3::CAMERA3_STREAM_ID_INVALID) {
58 ALOGE("%s: Surface groups not supported in case of composite streams!",
59 __FUNCTION__);
60 return BAD_VALUE;
61 }
62
63 if (isShared) {
64 ALOGE("%s: Shared surfaces not supported in case of composite streams!",
65 __FUNCTION__);
66 return BAD_VALUE;
67 }
68
Shuzhen Wang83bff122020-11-20 15:51:39 -080069 if (isMultiResolution) {
70 ALOGE("%s: Multi-resolution output not supported in case of composite streams!",
71 __FUNCTION__);
72 return BAD_VALUE;
73 }
74
Emilian Peev538c90e2018-12-17 18:03:19 +000075 return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation, id,
76 physicalCameraId, surfaceIds, streamSetId, isShared);
77}
78
79status_t CompositeStream::deleteStream() {
80 {
81 Mutex::Autolock l(mMutex);
82 mPendingCaptureResults.clear();
83 mCaptureResults.clear();
84 mFrameNumberMap.clear();
85 mErrorFrameNumbers.clear();
86 }
87
88 return deleteInternalStreams();
89}
90
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080091void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
92 const CameraMetadata& /*settings*/) {
Emilian Peev538c90e2018-12-17 18:03:19 +000093 Mutex::Autolock l(mMutex);
94 if (!mErrorState && (streamId == getStreamId())) {
95 mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
96 }
97}
98
99void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
100 Mutex::Autolock l(mMutex);
101 if (!mErrorState && !bufferInfo.mError) {
102 mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
103 mInputReadyCondition.signal();
104 }
105}
106
107void CompositeStream::eraseResult(int64_t frameNumber) {
108 Mutex::Autolock l(mMutex);
109
110 auto it = mPendingCaptureResults.find(frameNumber);
111 if (it == mPendingCaptureResults.end()) {
112 return;
113 }
114
115 it = mPendingCaptureResults.erase(it);
116}
117
118void CompositeStream::onResultAvailable(const CaptureResult& result) {
119 bool resultError = false;
120 {
121 Mutex::Autolock l(mMutex);
122
123 uint64_t frameNumber = result.mResultExtras.frameNumber;
124 bool resultReady = false;
125 auto it = mPendingCaptureResults.find(frameNumber);
126 if (it != mPendingCaptureResults.end()) {
127 it->second.append(result.mMetadata);
128 if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
129 auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
130 if (entry.count == 1) {
131 auto ts = entry.data.i64[0];
132 mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
133 resultReady = true;
134 } else {
135 ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
136 __FUNCTION__, frameNumber);
137 resultError = true;
138 }
139 mPendingCaptureResults.erase(it);
140 }
141 }
142
143 if (resultReady) {
144 mInputReadyCondition.signal();
145 }
146 }
147
148 if (resultError) {
149 onResultError(result.mResultExtras);
150 }
151}
152
153void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
154 Mutex::Autolock l(mMutex);
155 mErrorFrameNumbers.emplace(frameNumber);
156 mInputReadyCondition.signal();
157}
158
159status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
160 sp<CameraDeviceBase> device = mDevice.promote();
161 if (device.get() == nullptr) {
162 return NO_INIT;
163 }
164
165 auto ret = device->addBufferListenerForStream(streamId, this);
166 if (ret != OK) {
167 ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
168 }
169
170 return ret;
171}
172
173bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
174 auto ret = false;
175 switch (errorCode) {
176 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
177 onResultError(resultExtras);
178 break;
179 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
180 ret = onStreamBufferError(resultExtras);
181 break;
182 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
Shuzhen Wange8675782019-12-05 09:12:14 -0800183 onRequestError(resultExtras);
Emilian Peev538c90e2018-12-17 18:03:19 +0000184 break;
185 default:
186 ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
187 Mutex::Autolock l(mMutex);
188 mErrorState = true;
189 break;
190 }
191
192 return ret;
193}
194
Shuzhen Wange8675782019-12-05 09:12:14 -0800195void CompositeStream::notifyError(int64_t frameNumber, int32_t requestId) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000196 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
197 mRemoteCallback.promote();
198
199 if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
200 CaptureResultExtras extras;
201 extras.errorStreamId = getStreamId();
202 extras.frameNumber = frameNumber;
Shuzhen Wange8675782019-12-05 09:12:14 -0800203 extras.requestId = requestId;
Emilian Peev538c90e2018-12-17 18:03:19 +0000204 remoteCb->onDeviceError(
205 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
206 extras);
207 }
208}
209
Emilian Peevc0fe54c2020-03-11 14:05:07 -0700210void CompositeStream::switchToOffline() {
211 Mutex::Autolock l(mMutex);
212 mDevice.clear();
213}
214
Emilian Peev538c90e2018-12-17 18:03:19 +0000215}; // namespace camera3
216}; // namespace android