You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
7.0 KiB
219 lines
7.0 KiB
4 months ago
|
/*
|
||
|
* Copyright (C) 2018 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#define LOG_TAG "Camera3-CompositeStream"
|
||
|
#define ATRACE_TAG ATRACE_TAG_CAMERA
|
||
|
//#define LOG_NDEBUG 0
|
||
|
|
||
|
#include <utils/Log.h>
|
||
|
#include <utils/Trace.h>
|
||
|
|
||
|
#include "common/CameraDeviceBase.h"
|
||
|
#include "CameraDeviceClient.h"
|
||
|
#include "CompositeStream.h"
|
||
|
|
||
|
namespace android {
|
||
|
namespace camera3 {
|
||
|
|
||
|
CompositeStream::CompositeStream(sp<CameraDeviceBase> device,
|
||
|
wp<hardware::camera2::ICameraDeviceCallbacks> cb) :
|
||
|
mDevice(device),
|
||
|
mRemoteCallback(cb),
|
||
|
mNumPartialResults(1),
|
||
|
mErrorState(false) {
|
||
|
if (device != nullptr) {
|
||
|
CameraMetadata staticInfo = device->info();
|
||
|
camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
|
||
|
if (entry.count > 0) {
|
||
|
mNumPartialResults = entry.data.i32[0];
|
||
|
}
|
||
|
mStatusTracker = device->getStatusTracker();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
status_t CompositeStream::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) {
|
||
|
if (hasDeferredConsumer) {
|
||
|
ALOGE("%s: Deferred consumers not supported in case of composite streams!",
|
||
|
__FUNCTION__);
|
||
|
return BAD_VALUE;
|
||
|
}
|
||
|
|
||
|
if (streamSetId != camera3::CAMERA3_STREAM_ID_INVALID) {
|
||
|
ALOGE("%s: Surface groups not supported in case of composite streams!",
|
||
|
__FUNCTION__);
|
||
|
return BAD_VALUE;
|
||
|
}
|
||
|
|
||
|
if (isShared) {
|
||
|
ALOGE("%s: Shared surfaces not supported in case of composite streams!",
|
||
|
__FUNCTION__);
|
||
|
return BAD_VALUE;
|
||
|
}
|
||
|
|
||
|
if (isMultiResolution) {
|
||
|
ALOGE("%s: Multi-resolution output not supported in case of composite streams!",
|
||
|
__FUNCTION__);
|
||
|
return BAD_VALUE;
|
||
|
}
|
||
|
|
||
|
return createInternalStreams(consumers, hasDeferredConsumer, width, height, format, rotation,
|
||
|
id, physicalCameraId, sensorPixelModesUsed, surfaceIds, streamSetId, isShared);
|
||
|
}
|
||
|
|
||
|
status_t CompositeStream::deleteStream() {
|
||
|
{
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
mPendingCaptureResults.clear();
|
||
|
mCaptureResults.clear();
|
||
|
mFrameNumberMap.clear();
|
||
|
mErrorFrameNumbers.clear();
|
||
|
}
|
||
|
|
||
|
return deleteInternalStreams();
|
||
|
}
|
||
|
|
||
|
void CompositeStream::onBufferRequestForFrameNumber(uint64_t frameNumber, int streamId,
|
||
|
const CameraMetadata& /*settings*/) {
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
if (!mErrorState && (streamId == getStreamId())) {
|
||
|
mPendingCaptureResults.emplace(frameNumber, CameraMetadata());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompositeStream::onBufferReleased(const BufferInfo& bufferInfo) {
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
if (!mErrorState && !bufferInfo.mError) {
|
||
|
mFrameNumberMap.emplace(bufferInfo.mFrameNumber, bufferInfo.mTimestamp);
|
||
|
mInputReadyCondition.signal();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompositeStream::eraseResult(int64_t frameNumber) {
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
|
||
|
auto it = mPendingCaptureResults.find(frameNumber);
|
||
|
if (it == mPendingCaptureResults.end()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
it = mPendingCaptureResults.erase(it);
|
||
|
}
|
||
|
|
||
|
void CompositeStream::onResultAvailable(const CaptureResult& result) {
|
||
|
bool resultError = false;
|
||
|
{
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
|
||
|
uint64_t frameNumber = result.mResultExtras.frameNumber;
|
||
|
bool resultReady = false;
|
||
|
auto it = mPendingCaptureResults.find(frameNumber);
|
||
|
if (it != mPendingCaptureResults.end()) {
|
||
|
it->second.append(result.mMetadata);
|
||
|
if (result.mResultExtras.partialResultCount >= mNumPartialResults) {
|
||
|
auto entry = it->second.find(ANDROID_SENSOR_TIMESTAMP);
|
||
|
if (entry.count == 1) {
|
||
|
auto ts = entry.data.i64[0];
|
||
|
mCaptureResults.emplace(ts, std::make_tuple(frameNumber, it->second));
|
||
|
resultReady = true;
|
||
|
} else {
|
||
|
ALOGE("%s: Timestamp metadata entry missing for frameNumber: %" PRIu64,
|
||
|
__FUNCTION__, frameNumber);
|
||
|
resultError = true;
|
||
|
}
|
||
|
mPendingCaptureResults.erase(it);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (resultReady) {
|
||
|
mInputReadyCondition.signal();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (resultError) {
|
||
|
onResultError(result.mResultExtras);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompositeStream::flagAnErrorFrameNumber(int64_t frameNumber) {
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
mErrorFrameNumbers.emplace(frameNumber);
|
||
|
mInputReadyCondition.signal();
|
||
|
}
|
||
|
|
||
|
status_t CompositeStream::registerCompositeStreamListener(int32_t streamId) {
|
||
|
sp<CameraDeviceBase> device = mDevice.promote();
|
||
|
if (device.get() == nullptr) {
|
||
|
return NO_INIT;
|
||
|
}
|
||
|
|
||
|
auto ret = device->addBufferListenerForStream(streamId, this);
|
||
|
if (ret != OK) {
|
||
|
ALOGE("%s: Failed to register composite stream listener!", __FUNCTION__);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool CompositeStream::onError(int32_t errorCode, const CaptureResultExtras& resultExtras) {
|
||
|
auto ret = false;
|
||
|
switch (errorCode) {
|
||
|
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
|
||
|
onResultError(resultExtras);
|
||
|
break;
|
||
|
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
|
||
|
ret = onStreamBufferError(resultExtras);
|
||
|
break;
|
||
|
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
|
||
|
onRequestError(resultExtras);
|
||
|
break;
|
||
|
default:
|
||
|
ALOGE("%s: Unrecoverable error: %d detected!", __FUNCTION__, errorCode);
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
mErrorState = true;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void CompositeStream::notifyError(int64_t frameNumber, int32_t requestId) {
|
||
|
sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb =
|
||
|
mRemoteCallback.promote();
|
||
|
|
||
|
if ((frameNumber >= 0) && (remoteCb.get() != nullptr)) {
|
||
|
CaptureResultExtras extras;
|
||
|
extras.errorStreamId = getStreamId();
|
||
|
extras.frameNumber = frameNumber;
|
||
|
extras.requestId = requestId;
|
||
|
remoteCb->onDeviceError(
|
||
|
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
|
||
|
extras);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompositeStream::switchToOffline() {
|
||
|
Mutex::Autolock l(mMutex);
|
||
|
mDevice.clear();
|
||
|
}
|
||
|
|
||
|
}; // namespace camera3
|
||
|
}; // namespace android
|