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 std::string & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,std::vector<int> * surfaceIds,int streamSetId,bool isShared,bool isMultiResolution,int32_t colorSpace,int64_t dynamicProfile,int64_t streamUseCase,bool useReadoutTimestamp)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 std::string& physicalCameraId,
50         const std::unordered_set<int32_t> &sensorPixelModesUsed,
51         std::vector<int> * surfaceIds,
52         int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
53         int64_t dynamicProfile, int64_t streamUseCase, bool useReadoutTimestamp) {
54     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 
72     if (isMultiResolution) {
73         ALOGE("%s: Multi-resolution output not supported in case of composite streams!",
74                 __FUNCTION__);
75         return BAD_VALUE;
76     }
77 
78     return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation,
79             id, physicalCameraId, sensorPixelModesUsed, surfaceIds, streamSetId, isShared,
80             colorSpace, dynamicProfile, streamUseCase, useReadoutTimestamp);
81 }
82 
deleteStream()83 status_t CompositeStream::deleteStream() {
84     {
85         Mutex::Autolock l(mMutex);
86         mPendingCaptureResults.clear();
87         mCaptureResults.clear();
88         mFrameNumberMap.clear();
89         mErrorFrameNumbers.clear();
90         mRequestTimeMap.clear();
91     }
92 
93     return deleteInternalStreams();
94 }
95 
onBufferRequestForFrameNumber(uint64_t frameNumber,int streamId,const CameraMetadata &)96 void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
97         const CameraMetadata& /*settings*/) {
98     Mutex::Autolock l(mMutex);
99     if (!mErrorState && (streamId == getStreamId())) {
100         mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
101         auto ts = systemTime();
102         mRequestTimeMap.emplace(frameNumber, ts);
103     }
104 }
105 
onBufferReleased(const BufferInfo & bufferInfo)106 void 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 
eraseResult(int64_t frameNumber)114 void CompositeStream::eraseResult(int64_t frameNumber) {
115     Mutex::Autolock l(mMutex);
116 
117     auto requestTimeIt = mRequestTimeMap.find(frameNumber);
118     if (requestTimeIt != mRequestTimeMap.end()) {
119         mRequestTimeMap.erase(requestTimeIt);
120     }
121 
122     auto it = mPendingCaptureResults.find(frameNumber);
123     if (it == mPendingCaptureResults.end()) {
124         return;
125     }
126 
127     it = mPendingCaptureResults.erase(it);
128 }
129 
onResultAvailable(const CaptureResult & result)130 void 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 
flagAnErrorFrameNumber(int64_t frameNumber)165 void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
166     Mutex::Autolock l(mMutex);
167     mErrorFrameNumbers.emplace(frameNumber);
168     mInputReadyCondition.signal();
169 }
170 
registerCompositeStreamListener(int32_t streamId)171 status_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 
onError(int32_t errorCode,const CaptureResultExtras & resultExtras)185 bool 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:
195             onRequestError(resultExtras);
196             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 
notifyError(int64_t frameNumber,int32_t requestId)207 void CompositeStream::notifyError(int64_t frameNumber, int32_t requestId) {
208     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;
215         extras.requestId = requestId;
216         remoteCb->onDeviceError(
217                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
218                 extras);
219     }
220 }
221 
switchToOffline()222 void CompositeStream::switchToOffline() {
223     Mutex::Autolock l(mMutex);
224     mDevice.clear();
225 }
226 
227 }; // namespace camera3
228 }; // namespace android
229