1 /*
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
28 namespace android {
29 namespace camera3 {
30
CompositeStream(sp<CameraDeviceBase> device,wp<hardware::camera2::ICameraDeviceCallbacks> cb)31 CompositeStream::CompositeStream(sp<CameraDeviceBase> device,
32 wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
33 mDevice(device),
34 mRemoteCallback(cb),
35 mNumPartialResults(1),
36 mErrorState(false) {
37 if (device != nullptr) {
38 CameraMetadata staticInfo = device->info();
39 camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
40 if (entry.count > 0) {
41 mNumPartialResults = entry.data.i32[0];
42 }
43 mStatusTracker = device->getStatusTracker();
44 }
45 }
46
createStream(const std::vector<sp<Surface>> & consumers,bool hasDeferredConsumer,uint32_t width,uint32_t height,int format,camera_stream_rotation_t rotation,int * id,const String8 & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,std::vector<int> * surfaceIds,int streamSetId,bool isShared,bool isMultiResolution)47 status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
48 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
49 camera_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
50 const std::unordered_set<int32_t> &sensorPixelModesUsed,
51 std::vector<int> * surfaceIds,
52 int streamSetId, bool isShared, bool isMultiResolution) {
53 if (hasDeferredConsumer) {
54 ALOGE("%s: Deferred consumers not supported in case of composite streams!",
55 __FUNCTION__);
56 return BAD_VALUE;
57 }
58
59 if (streamSetId != camera3::CAMERA3_STREAM_ID_INVALID) {
60 ALOGE("%s: Surface groups not supported in case of composite streams!",
61 __FUNCTION__);
62 return BAD_VALUE;
63 }
64
65 if (isShared) {
66 ALOGE("%s: Shared surfaces not supported in case of composite streams!",
67 __FUNCTION__);
68 return BAD_VALUE;
69 }
70
71 if (isMultiResolution) {
72 ALOGE("%s: Multi-resolution output not supported in case of composite streams!",
73 __FUNCTION__);
74 return BAD_VALUE;
75 }
76
77 return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation,
78 id, physicalCameraId, sensorPixelModesUsed, surfaceIds, streamSetId, isShared);
79 }
80
deleteStream()81 status_t CompositeStream::deleteStream() {
82 {
83 Mutex::Autolock l(mMutex);
84 mPendingCaptureResults.clear();
85 mCaptureResults.clear();
86 mFrameNumberMap.clear();
87 mErrorFrameNumbers.clear();
88 }
89
90 return deleteInternalStreams();
91 }
92
onBufferRequestForFrameNumber(uint64_t frameNumber,int streamId,const CameraMetadata &)93 void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
94 const CameraMetadata& /*settings*/) {
95 Mutex::Autolock l(mMutex);
96 if (!mErrorState && (streamId == getStreamId())) {
97 mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
98 }
99 }
100
onBufferReleased(const BufferInfo & bufferInfo)101 void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
102 Mutex::Autolock l(mMutex);
103 if (!mErrorState && !bufferInfo.mError) {
104 mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
105 mInputReadyCondition.signal();
106 }
107 }
108
eraseResult(int64_t frameNumber)109 void CompositeStream::eraseResult(int64_t frameNumber) {
110 Mutex::Autolock l(mMutex);
111
112 auto it = mPendingCaptureResults.find(frameNumber);
113 if (it == mPendingCaptureResults.end()) {
114 return;
115 }
116
117 it = mPendingCaptureResults.erase(it);
118 }
119
onResultAvailable(const CaptureResult & result)120 void CompositeStream::onResultAvailable(const CaptureResult& result) {
121 bool resultError = false;
122 {
123 Mutex::Autolock l(mMutex);
124
125 uint64_t frameNumber = result.mResultExtras.frameNumber;
126 bool resultReady = false;
127 auto it = mPendingCaptureResults.find(frameNumber);
128 if (it != mPendingCaptureResults.end()) {
129 it->second.append(result.mMetadata);
130 if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
131 auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
132 if (entry.count == 1) {
133 auto ts = entry.data.i64[0];
134 mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
135 resultReady = true;
136 } else {
137 ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
138 __FUNCTION__, frameNumber);
139 resultError = true;
140 }
141 mPendingCaptureResults.erase(it);
142 }
143 }
144
145 if (resultReady) {
146 mInputReadyCondition.signal();
147 }
148 }
149
150 if (resultError) {
151 onResultError(result.mResultExtras);
152 }
153 }
154
flagAnErrorFrameNumber(int64_t frameNumber)155 void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
156 Mutex::Autolock l(mMutex);
157 mErrorFrameNumbers.emplace(frameNumber);
158 mInputReadyCondition.signal();
159 }
160
registerCompositeStreamListener(int32_t streamId)161 status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
162 sp<CameraDeviceBase> device = mDevice.promote();
163 if (device.get() == nullptr) {
164 return NO_INIT;
165 }
166
167 auto ret = device->addBufferListenerForStream(streamId, this);
168 if (ret != OK) {
169 ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
170 }
171
172 return ret;
173 }
174
onError(int32_t errorCode,const CaptureResultExtras & resultExtras)175 bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
176 auto ret = false;
177 switch (errorCode) {
178 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
179 onResultError(resultExtras);
180 break;
181 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
182 ret = onStreamBufferError(resultExtras);
183 break;
184 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
185 onRequestError(resultExtras);
186 break;
187 default:
188 ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
189 Mutex::Autolock l(mMutex);
190 mErrorState = true;
191 break;
192 }
193
194 return ret;
195 }
196
notifyError(int64_t frameNumber,int32_t requestId)197 void CompositeStream::notifyError(int64_t frameNumber, int32_t requestId) {
198 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
199 mRemoteCallback.promote();
200
201 if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
202 CaptureResultExtras extras;
203 extras.errorStreamId = getStreamId();
204 extras.frameNumber = frameNumber;
205 extras.requestId = requestId;
206 remoteCb->onDeviceError(
207 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
208 extras);
209 }
210 }
211
switchToOffline()212 void CompositeStream::switchToOffline() {
213 Mutex::Autolock l(mMutex);
214 mDevice.clear();
215 }
216
217 }; // namespace camera3
218 }; // namespace android
219