blob: 796bf42ae0a663307034e9977523b41b70c7d838 [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
31CompositeStream::CompositeStream(wp<CameraDeviceBase> device,
32 wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
33 mDevice(device),
34 mRemoteCallback(cb),
35 mNumPartialResults(1),
36 mErrorState(false) {
37 sp<CameraDeviceBase> cameraDevice = device.promote();
38 if (cameraDevice.get() != nullptr) {
39 CameraMetadata staticInfo = cameraDevice->info();
40 camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
41 if (entry.count > 0) {
42 mNumPartialResults = entry.data.i32[0];
43 }
44 }
45}
46
47status_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
73status_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
85void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId) {
86 Mutex::Autolock l(mMutex);
87 if (!mErrorState && (streamId == getStreamId())) {
88 mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
89 }
90}
91
92void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
93 Mutex::Autolock l(mMutex);
94 if (!mErrorState && !bufferInfo.mError) {
95 mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
96 mInputReadyCondition.signal();
97 }
98}
99
100void CompositeStream::eraseResult(int64_t frameNumber) {
101 Mutex::Autolock l(mMutex);
102
103 auto it = mPendingCaptureResults.find(frameNumber);
104 if (it == mPendingCaptureResults.end()) {
105 return;
106 }
107
108 it = mPendingCaptureResults.erase(it);
109}
110
111void CompositeStream::onResultAvailable(const CaptureResult& result) {
112 bool resultError = false;
113 {
114 Mutex::Autolock l(mMutex);
115
116 uint64_t frameNumber = result.mResultExtras.frameNumber;
117 bool resultReady = false;
118 auto it = mPendingCaptureResults.find(frameNumber);
119 if (it != mPendingCaptureResults.end()) {
120 it->second.append(result.mMetadata);
121 if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
122 auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
123 if (entry.count == 1) {
124 auto ts = entry.data.i64[0];
125 mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
126 resultReady = true;
127 } else {
128 ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
129 __FUNCTION__, frameNumber);
130 resultError = true;
131 }
132 mPendingCaptureResults.erase(it);
133 }
134 }
135
136 if (resultReady) {
137 mInputReadyCondition.signal();
138 }
139 }
140
141 if (resultError) {
142 onResultError(result.mResultExtras);
143 }
144}
145
146void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
147 Mutex::Autolock l(mMutex);
148 mErrorFrameNumbers.emplace(frameNumber);
149 mInputReadyCondition.signal();
150}
151
152status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
153 sp<CameraDeviceBase> device = mDevice.promote();
154 if (device.get() == nullptr) {
155 return NO_INIT;
156 }
157
158 auto ret = device->addBufferListenerForStream(streamId, this);
159 if (ret != OK) {
160 ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
161 }
162
163 return ret;
164}
165
166bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
167 auto ret = false;
168 switch (errorCode) {
169 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
170 onResultError(resultExtras);
171 break;
172 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
173 ret = onStreamBufferError(resultExtras);
174 break;
175 case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
176 // Invalid request, this shouldn't affect composite streams.
177 break;
178 default:
179 ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
180 Mutex::Autolock l(mMutex);
181 mErrorState = true;
182 break;
183 }
184
185 return ret;
186}
187
188void CompositeStream::notifyError(int64_t frameNumber) {
189 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
190 mRemoteCallback.promote();
191
192 if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
193 CaptureResultExtras extras;
194 extras.errorStreamId = getStreamId();
195 extras.frameNumber = frameNumber;
196 remoteCb->onDeviceError(
197 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
198 extras);
199 }
200}
201
202}; // namespace camera3
203}; // namespace android