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