Camera: Avoid stream re-configuration when format gets overridden

It is allowed and expected some stream formats to get overriden
by the Hal implementation. In such cases the original format should
be stored and made available to device clients.

Bug: 64571102
Test: Camera CTS
Change-Id: Ic1153390e0c4d194475fbda8c8a13323bd7e73c0
gugelfrei
Emilian Peev 7 years ago
parent c4a226e858
commit 710c142d6a

@ -121,18 +121,17 @@ status_t CallbackProcessor::updateStream(const Parameters &params) {
if (mCallbackStreamId != NO_STREAM) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight, currentFormat;
res = device->getStreamInfo(mCallbackStreamId,
&currentWidth, &currentHeight, &currentFormat, 0);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mCallbackStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying callback output stream info: "
"%s (%d)", __FUNCTION__, mId,
strerror(-res), res);
return res;
}
if (currentWidth != (uint32_t)params.previewWidth ||
currentHeight != (uint32_t)params.previewHeight ||
currentFormat != (uint32_t)callbackFormat) {
if (streamInfo.width != (uint32_t)params.previewWidth ||
streamInfo.height != (uint32_t)params.previewHeight ||
!streamInfo.matchFormat((uint32_t)callbackFormat)) {
// Since size should only change while preview is not running,
// assuming that all existing use of old callback stream is
// completed.

@ -136,17 +136,16 @@ status_t JpegProcessor::updateStream(const Parameters &params) {
if (mCaptureStreamId != NO_STREAM) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight;
res = device->getStreamInfo(mCaptureStreamId,
&currentWidth, &currentHeight, 0, 0);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mCaptureStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying capture output stream info: "
"%s (%d)", __FUNCTION__,
mId, strerror(-res), res);
return res;
}
if (currentWidth != (uint32_t)params.pictureWidth ||
currentHeight != (uint32_t)params.pictureHeight) {
if (streamInfo.width != (uint32_t)params.pictureWidth ||
streamInfo.height != (uint32_t)params.pictureHeight) {
ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
__FUNCTION__, mId, mCaptureStreamId);
res = device->deleteStream(mCaptureStreamId);

@ -161,18 +161,17 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
if (mPreviewStreamId != NO_STREAM) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight;
res = device->getStreamInfo(mPreviewStreamId,
&currentWidth, &currentHeight, 0, 0);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mPreviewStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying preview stream info: "
"%s (%d)", __FUNCTION__, mId, strerror(-res), res);
return res;
}
if (currentWidth != (uint32_t)params.previewWidth ||
currentHeight != (uint32_t)params.previewHeight) {
if (streamInfo.width != (uint32_t)params.previewWidth ||
streamInfo.height != (uint32_t)params.previewHeight) {
ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
__FUNCTION__, mId, currentWidth, currentHeight,
__FUNCTION__, mId, streamInfo.width, streamInfo.height,
params.previewWidth, params.previewHeight);
res = device->waitUntilDrained();
if (res != OK) {
@ -312,10 +311,8 @@ status_t StreamingProcessor::recordingStreamNeedsUpdate(
return INVALID_OPERATION;
}
uint32_t currentWidth, currentHeight, currentFormat;
android_dataspace currentDataSpace;
res = device->getStreamInfo(mRecordingStreamId,
&currentWidth, &currentHeight, &currentFormat, &currentDataSpace);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mRecordingStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying recording output stream info: "
"%s (%d)", __FUNCTION__, mId,
@ -324,10 +321,10 @@ status_t StreamingProcessor::recordingStreamNeedsUpdate(
}
if (mRecordingWindow == nullptr ||
currentWidth != (uint32_t)params.videoWidth ||
currentHeight != (uint32_t)params.videoHeight ||
currentFormat != (uint32_t)params.videoFormat ||
currentDataSpace != params.videoDataSpace) {
streamInfo.width != (uint32_t)params.videoWidth ||
streamInfo.height != (uint32_t)params.videoHeight ||
!streamInfo.matchFormat((uint32_t)params.videoFormat) ||
streamInfo.dataSpace != params.videoDataSpace) {
*needsUpdate = true;
return res;
}
@ -348,22 +345,18 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
if (mRecordingStreamId != NO_STREAM) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight;
uint32_t currentFormat;
android_dataspace currentDataSpace;
res = device->getStreamInfo(mRecordingStreamId,
&currentWidth, &currentHeight,
&currentFormat, &currentDataSpace);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mRecordingStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying recording output stream info: "
"%s (%d)", __FUNCTION__, mId,
strerror(-res), res);
return res;
}
if (currentWidth != (uint32_t)params.videoWidth ||
currentHeight != (uint32_t)params.videoHeight ||
currentFormat != (uint32_t)params.videoFormat ||
currentDataSpace != params.videoDataSpace) {
if (streamInfo.width != (uint32_t)params.videoWidth ||
streamInfo.height != (uint32_t)params.videoHeight ||
!streamInfo.matchFormat((uint32_t)params.videoFormat) ||
streamInfo.dataSpace != params.videoDataSpace) {
// TODO: Should wait to be sure previous recording has finished
res = device->deleteStream(mRecordingStreamId);

@ -233,17 +233,16 @@ status_t ZslProcessor::updateStream(const Parameters &params) {
if ((mZslStreamId != NO_STREAM) || (mInputStreamId != NO_STREAM)) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight;
res = device->getStreamInfo(mZslStreamId,
&currentWidth, &currentHeight, 0, 0);
CameraDeviceBase::StreamInfo streamInfo;
res = device->getStreamInfo(mZslStreamId, &streamInfo);
if (res != OK) {
ALOGE("%s: Camera %d: Error querying capture output stream info: "
"%s (%d)", __FUNCTION__,
client->getCameraId(), strerror(-res), res);
return res;
}
if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
if (streamInfo.width != (uint32_t)params.fastInfo.arrayWidth ||
streamInfo.height != (uint32_t)params.fastInfo.arrayHeight) {
if (mZslStreamId != NO_STREAM) {
ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
"dimensions changed",

@ -142,12 +142,32 @@ class CameraDeviceBase : public virtual RefBase {
virtual status_t createInputStream(uint32_t width, uint32_t height,
int32_t format, /*out*/ int32_t *id) = 0;
struct StreamInfo {
uint32_t width;
uint32_t height;
uint32_t format;
bool formatOverridden;
uint32_t originalFormat;
android_dataspace dataSpace;
StreamInfo() : width(0), height(0), format(0), formatOverridden(false), originalFormat(0),
dataSpace(HAL_DATASPACE_UNKNOWN) {}
/**
* Check whether the format matches the current or the original one in case
* it got overridden.
*/
bool matchFormat(uint32_t clientFormat) {
if ((formatOverridden && (originalFormat == clientFormat)) ||
(format == clientFormat)) {
return true;
}
return false;
}
};
/**
* Get information about a given stream.
*/
virtual status_t getStreamInfo(int id,
uint32_t *width, uint32_t *height,
uint32_t *format, android_dataspace *dataSpace) = 0;
virtual status_t getStreamInfo(int id, StreamInfo *streamInfo) = 0;
/**
* Set stream gralloc buffer transform

@ -1345,10 +1345,11 @@ status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
return OK;
}
status_t Camera3Device::getStreamInfo(int id,
uint32_t *width, uint32_t *height,
uint32_t *format, android_dataspace *dataSpace) {
status_t Camera3Device::getStreamInfo(int id, StreamInfo *streamInfo) {
ATRACE_CALL();
if (nullptr == streamInfo) {
return BAD_VALUE;
}
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@ -1375,10 +1376,12 @@ status_t Camera3Device::getStreamInfo(int id,
return idx;
}
if (width) *width = mOutputStreams[idx]->getWidth();
if (height) *height = mOutputStreams[idx]->getHeight();
if (format) *format = mOutputStreams[idx]->getFormat();
if (dataSpace) *dataSpace = mOutputStreams[idx]->getDataSpace();
streamInfo->width = mOutputStreams[idx]->getWidth();
streamInfo->height = mOutputStreams[idx]->getHeight();
streamInfo->format = mOutputStreams[idx]->getFormat();
streamInfo->dataSpace = mOutputStreams[idx]->getDataSpace();
streamInfo->formatOverridden = mOutputStreams[idx]->isFormatOverridden();
streamInfo->originalFormat = mOutputStreams[idx]->getOriginalFormat();
return OK;
}
@ -3233,6 +3236,8 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
}
HalStream &src = finalConfiguration.streams[realIdx];
Camera3Stream* dstStream = Camera3Stream::cast(dst);
dstStream->setFormatOverride(false);
int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
if (dst->format != overrideFormat) {
@ -3240,6 +3245,8 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
streamId, dst->format);
}
} else {
dstStream->setFormatOverride((dst->format != overrideFormat) ? true : false);
dstStream->setOriginalFormat(dst->format);
// Override allowed with IMPLEMENTATION_DEFINED
dst->format = overrideFormat;
}

@ -128,9 +128,7 @@ class Camera3Device :
uint32_t width, uint32_t height, int format,
int *id) override;
status_t getStreamInfo(int id,
uint32_t *width, uint32_t *height,
uint32_t *format, android_dataspace *dataSpace) override;
status_t getStreamInfo(int id, StreamInfo *streamInfo) override;
status_t setStreamTransform(int id, int transform) override;
status_t deleteStream(int id) override;

@ -62,7 +62,9 @@ Camera3Stream::Camera3Stream(int id,
mPrepared(false),
mPreparedBufferIdx(0),
mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
mBufferLimitLatency(kBufferLimitLatencyBinSize) {
mBufferLimitLatency(kBufferLimitLatencyBinSize),
mFormatOverridden(false),
mOriginalFormat(-1) {
camera3_stream::stream_type = type;
camera3_stream::width = width;
@ -112,6 +114,22 @@ void Camera3Stream::setUsage(uint64_t usage) {
mUsage = usage;
}
void Camera3Stream::setFormatOverride(bool formatOverridden) {
mFormatOverridden = formatOverridden;
}
bool Camera3Stream::isFormatOverridden() {
return mFormatOverridden;
}
void Camera3Stream::setOriginalFormat(int originalFormat) {
mOriginalFormat = originalFormat;
}
int Camera3Stream::getOriginalFormat() {
return mOriginalFormat;
}
camera3_stream* Camera3Stream::startConfiguration() {
ATRACE_CALL();
Mutex::Autolock l(mLock);

@ -146,6 +146,10 @@ class Camera3Stream :
android_dataspace getDataSpace() const;
uint64_t getUsage() const;
void setUsage(uint64_t usage);
void setFormatOverride(bool formatOverriden);
bool isFormatOverridden();
void setOriginalFormat(int originalFormat);
int getOriginalFormat();
camera3_stream* asHalStream() override {
return this;
@ -514,6 +518,10 @@ class Camera3Stream :
// max_buffers.
static const int32_t kBufferLimitLatencyBinSize = 33; //in ms
CameraLatencyHistogram mBufferLimitLatency;
//Keep track of original format in case it gets overridden
bool mFormatOverridden;
int mOriginalFormat;
}; // class Camera3Stream
}; // namespace camera3

@ -71,6 +71,10 @@ class Camera3StreamInterface : public virtual RefBase {
virtual uint32_t getHeight() const = 0;
virtual int getFormat() const = 0;
virtual android_dataspace getDataSpace() const = 0;
virtual void setFormatOverride(bool formatOverriden) = 0;
virtual bool isFormatOverridden() = 0;
virtual void setOriginalFormat(int originalFormat) = 0;
virtual int getOriginalFormat() = 0;
/**
* Get a HAL3 handle for the stream, without starting stream configuration.

Loading…
Cancel
Save