Emilian Peev | 538c90e | 2018-12-17 18:03:19 +0000 | [diff] [blame] | 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 | |
| 31 | CompositeStream::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 | |
| 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 | |
| 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 | |
Shuzhen Wang | 68ac7ad | 2019-01-30 14:03:28 -0800 | [diff] [blame] | 85 | void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId, |
| 86 | const CameraMetadata& /*settings*/) { |
Emilian Peev | 538c90e | 2018-12-17 18:03:19 +0000 | [diff] [blame] | 87 | Mutex::Autolock l(mMutex); |
| 88 | if (!mErrorState && (streamId == getStreamId())) { |
| 89 | mPendingCaptureResults.emplace(frameNumber, CameraMetadata()); |
| 90 | } |
| 91 | } |
| 92 | |
| 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 | |
| 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 | |
| 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 | |
| 147 | void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) { |
| 148 | Mutex::Autolock l(mMutex); |
| 149 | mErrorFrameNumbers.emplace(frameNumber); |
| 150 | mInputReadyCondition.signal(); |
| 151 | } |
| 152 | |
| 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 | |
| 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 | // Invalid request, this shouldn't affect composite streams. |
| 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 | |
| 189 | void CompositeStream::notifyError(int64_t frameNumber) { |
| 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 | remoteCb->onDeviceError( |
| 198 | hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER, |
| 199 | extras); |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | }; // namespace camera3 |
| 204 | }; // namespace android |