mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge changes I20310606,Ic23b7fb2 into pi-dev
* changes: Camera: more external camera CTS fix Camera: various external camera CTS fixes
This commit is contained in:
committed by
Android (Google) Code Review
commit
ba20b76deb
@@ -983,15 +983,15 @@ bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
|
||||
camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
|
||||
if (entry.count) {
|
||||
focal_length = entry.data.f[0];
|
||||
|
||||
if (!setFocalLength(
|
||||
static_cast<uint32_t>(focal_length * kRationalPrecision),
|
||||
kRationalPrecision)) {
|
||||
ALOGE("%s: setting focal length failed.", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ALOGE("%s: Cannot find focal length in metadata.", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
if (!setFocalLength(
|
||||
static_cast<uint32_t>(focal_length * kRationalPrecision),
|
||||
kRationalPrecision)) {
|
||||
ALOGE("%s: setting focal length failed.", __FUNCTION__);
|
||||
return false;
|
||||
ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
|
||||
|
||||
@@ -284,13 +284,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
|
||||
const int32_t jpegMaxSize = mCfg.maxJpegBufSize;
|
||||
UPDATE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
|
||||
|
||||
const uint8_t jpegQuality = 90;
|
||||
UPDATE(ANDROID_JPEG_QUALITY, &jpegQuality, 1);
|
||||
UPDATE(ANDROID_JPEG_THUMBNAIL_QUALITY, &jpegQuality, 1);
|
||||
|
||||
const int32_t jpegOrientation = 0;
|
||||
UPDATE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
|
||||
|
||||
// android.lens
|
||||
const uint8_t focusDistanceCalibration =
|
||||
ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
|
||||
@@ -322,7 +315,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
|
||||
// This means pipeline latency of X frame intervals. The maximum number is 4.
|
||||
const uint8_t requestPipelineMaxDepth = 4;
|
||||
UPDATE(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &requestPipelineMaxDepth, 1);
|
||||
UPDATE(ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);
|
||||
|
||||
// Three numbers represent the maximum numbers of different types of output
|
||||
// streams simultaneously. The types are raw sensor, processed (but not
|
||||
@@ -355,7 +347,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
|
||||
ANDROID_SENSOR_TEST_PATTERN_MODE_OFF};
|
||||
UPDATE(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, testPatternModes,
|
||||
ARRAY_SIZE(testPatternModes));
|
||||
UPDATE(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes[0], 1);
|
||||
|
||||
const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
|
||||
UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1);
|
||||
@@ -576,7 +567,6 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
|
||||
std::vector<int32_t> streamConfigurations;
|
||||
std::vector<int64_t> minFrameDurations;
|
||||
std::vector<int64_t> stallDurations;
|
||||
int64_t maxFrameDuration = 0;
|
||||
int32_t maxFps = std::numeric_limits<int32_t>::min();
|
||||
int32_t minFps = std::numeric_limits<int32_t>::max();
|
||||
std::set<int32_t> framerates;
|
||||
@@ -604,9 +594,6 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
|
||||
if (frameDuration < minFrameDuration) {
|
||||
minFrameDuration = frameDuration;
|
||||
}
|
||||
if (frameDuration > maxFrameDuration) {
|
||||
maxFrameDuration = frameDuration;
|
||||
}
|
||||
int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
|
||||
if (minFps > frameRateInt) {
|
||||
minFps = frameRateInt;
|
||||
@@ -639,14 +626,15 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
|
||||
}
|
||||
|
||||
std::vector<int32_t> fpsRanges;
|
||||
// Variable range
|
||||
fpsRanges.push_back(minFps);
|
||||
fpsRanges.push_back(maxFps);
|
||||
// Fixed ranges
|
||||
// FPS ranges
|
||||
for (const auto& framerate : framerates) {
|
||||
fpsRanges.push_back(framerate);
|
||||
// Empirical: webcams often have close to 2x fps error and cannot support fixed fps range
|
||||
fpsRanges.push_back(framerate / 2);
|
||||
fpsRanges.push_back(framerate);
|
||||
}
|
||||
minFps /= 2;
|
||||
int64_t maxFrameDuration = 1000000000LL / minFps;
|
||||
|
||||
UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(),
|
||||
fpsRanges.size());
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ static constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
|
||||
const int kBadFramesAfterStreamOn = 1; // drop x frames after streamOn to get rid of some initial
|
||||
// bad frames. TODO: develop a better bad frame detection
|
||||
// method
|
||||
constexpr int MAX_RETRY = 15; // Allow retry some ioctl failures a few times to account for some
|
||||
// webcam showing temporarily ioctl failures.
|
||||
constexpr int IOCTL_RETRY_SLEEP_US = 33000; // 33ms * MAX_RETRY = 5 seconds
|
||||
|
||||
bool tryLock(Mutex& mutex)
|
||||
{
|
||||
@@ -1480,6 +1483,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
|
||||
|
||||
int jpegQuality, thumbQuality;
|
||||
Size thumbSize;
|
||||
bool outputThumbnail = true;
|
||||
|
||||
if (req->setting.exists(ANDROID_JPEG_QUALITY)) {
|
||||
camera_metadata_entry entry =
|
||||
@@ -1505,6 +1509,9 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
|
||||
thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]),
|
||||
static_cast<uint32_t>(entry.data.i32[1])
|
||||
};
|
||||
if (thumbSize.width == 0 && thumbSize.height == 0) {
|
||||
outputThumbnail = false;
|
||||
}
|
||||
} else {
|
||||
return lfail(
|
||||
"%s: ANDROID_JPEG_THUMBNAIL_SIZE not set", __FUNCTION__);
|
||||
@@ -1532,14 +1539,16 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
|
||||
/* Hold actual thumbnail and main image code sizes */
|
||||
size_t thumbCodeSize = 0, jpegCodeSize = 0;
|
||||
/* Temporary thumbnail code buffer */
|
||||
std::vector<uint8_t> thumbCode(maxThumbCodeSize);
|
||||
std::vector<uint8_t> thumbCode(outputThumbnail ? maxThumbCodeSize : 0);
|
||||
|
||||
YCbCrLayout yu12Thumb;
|
||||
ret = cropAndScaleThumbLocked(mYu12Frame, thumbSize, &yu12Thumb);
|
||||
if (outputThumbnail) {
|
||||
ret = cropAndScaleThumbLocked(mYu12Frame, thumbSize, &yu12Thumb);
|
||||
|
||||
if (ret != 0) {
|
||||
return lfail(
|
||||
"%s: crop and scale thumbnail failed!", __FUNCTION__);
|
||||
if (ret != 0) {
|
||||
return lfail(
|
||||
"%s: crop and scale thumbnail failed!", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scale and crop main jpeg */
|
||||
@@ -1550,12 +1559,14 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
|
||||
}
|
||||
|
||||
/* Encode the thumbnail image */
|
||||
ret = encodeJpegYU12(thumbSize, yu12Thumb,
|
||||
thumbQuality, 0, 0,
|
||||
&thumbCode[0], maxThumbCodeSize, thumbCodeSize);
|
||||
if (outputThumbnail) {
|
||||
ret = encodeJpegYU12(thumbSize, yu12Thumb,
|
||||
thumbQuality, 0, 0,
|
||||
&thumbCode[0], maxThumbCodeSize, thumbCodeSize);
|
||||
|
||||
if (ret != 0) {
|
||||
return lfail("%s: encodeJpegYU12 failed with %d",__FUNCTION__, ret);
|
||||
if (ret != 0) {
|
||||
return lfail("%s: thumbnail encodeJpegYU12 failed with %d",__FUNCTION__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Combine camera characteristics with request settings to form EXIF
|
||||
@@ -1570,11 +1581,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
|
||||
|
||||
utils->setFromMetadata(meta, jpegSize.width, jpegSize.height);
|
||||
|
||||
/* Check if we made a non-zero-sized thumbnail. Currently not possible
|
||||
* that we got this far and the code is size 0, but if this code moves
|
||||
* around it might become relevant again */
|
||||
|
||||
ret = utils->generateApp1(thumbCodeSize ? &thumbCode[0] : 0, thumbCodeSize);
|
||||
ret = utils->generateApp1(outputThumbnail ? &thumbCode[0] : 0, thumbCodeSize);
|
||||
|
||||
if (!ret) {
|
||||
return lfail("%s: generating APP1 failed", __FUNCTION__);
|
||||
@@ -2109,8 +2116,20 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(
|
||||
fmt.fmt.pix.pixelformat = v4l2Fmt.fourcc;
|
||||
ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
|
||||
if (ret < 0) {
|
||||
ALOGE("%s: S_FMT ioctl failed: %s", __FUNCTION__, strerror(errno));
|
||||
return -errno;
|
||||
int numAttempt = 0;
|
||||
while (ret < 0) {
|
||||
ALOGW("%s: VIDIOC_S_FMT failed, wait 33ms and try again", __FUNCTION__);
|
||||
usleep(IOCTL_RETRY_SLEEP_US); // sleep 100 ms and try again
|
||||
ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
|
||||
if (numAttempt == MAX_RETRY) {
|
||||
break;
|
||||
}
|
||||
numAttempt++;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ALOGE("%s: S_FMT ioctl failed: %s", __FUNCTION__, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (v4l2Fmt.width != fmt.fmt.pix.width || v4l2Fmt.height != fmt.fmt.pix.height ||
|
||||
@@ -2199,9 +2218,22 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(
|
||||
|
||||
// VIDIOC_STREAMON: start streaming
|
||||
v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type)) < 0) {
|
||||
ALOGE("%s: VIDIOC_STREAMON failed: %s", __FUNCTION__, strerror(errno));
|
||||
return -errno;
|
||||
ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
|
||||
if (ret < 0) {
|
||||
int numAttempt = 0;
|
||||
while (ret < 0) {
|
||||
ALOGW("%s: VIDIOC_STREAMON failed, wait 33ms and try again", __FUNCTION__);
|
||||
usleep(IOCTL_RETRY_SLEEP_US); // sleep 100 ms and try again
|
||||
ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
|
||||
if (numAttempt == MAX_RETRY) {
|
||||
break;
|
||||
}
|
||||
numAttempt++;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ALOGE("%s: VIDIOC_STREAMON ioctl failed: %s", __FUNCTION__, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
// Swallow first few frames after streamOn to account for bad frames from some devices
|
||||
@@ -2220,6 +2252,8 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(
|
||||
}
|
||||
}
|
||||
|
||||
ALOGI("%s: start V4L2 streaming %dx%d@%ffps",
|
||||
__FUNCTION__, v4l2Fmt.width, v4l2Fmt.height, fps);
|
||||
mV4l2StreamingFmt = v4l2Fmt;
|
||||
mV4l2Streaming = true;
|
||||
return OK;
|
||||
@@ -2388,6 +2422,7 @@ Status ExternalCameraDeviceSession::configureStreams(
|
||||
uint32_t maxDim = 0;
|
||||
for (const auto& stream : config.streams) {
|
||||
float aspectRatio = ASPECT_RATIO(stream);
|
||||
ALOGI("%s: request stream %dx%d", __FUNCTION__, stream.width, stream.height);
|
||||
if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
|
||||
(mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
|
||||
desiredAr = aspectRatio;
|
||||
@@ -2572,6 +2607,9 @@ status_t ExternalCameraDeviceSession::initDefaultRequests() {
|
||||
const uint8_t nrMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
|
||||
UPDATE(md, ANDROID_NOISE_REDUCTION_MODE, &nrMode, 1);
|
||||
|
||||
const int32_t testPatternModes = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
|
||||
UPDATE(md, ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes, 1);
|
||||
|
||||
const uint8_t fdMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
|
||||
UPDATE(md, ANDROID_STATISTICS_FACE_DETECT_MODE, &fdMode, 1);
|
||||
|
||||
@@ -2596,7 +2634,7 @@ status_t ExternalCameraDeviceSession::initDefaultRequests() {
|
||||
}
|
||||
}
|
||||
int32_t defaultFramerate = support30Fps ? 30 : maxFps;
|
||||
int32_t defaultFpsRange[] = {defaultFramerate, defaultFramerate};
|
||||
int32_t defaultFpsRange[] = {defaultFramerate / 2, defaultFramerate};
|
||||
UPDATE(md, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, defaultFpsRange, ARRAY_SIZE(defaultFpsRange));
|
||||
|
||||
uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
|
||||
@@ -2691,6 +2729,10 @@ status_t ExternalCameraDeviceSession::fillCaptureResult(
|
||||
const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
|
||||
UPDATE(md, ANDROID_FLASH_STATE, &flashState, 1);
|
||||
|
||||
// This means pipeline latency of X frame intervals. The maximum number is 4.
|
||||
const uint8_t requestPipelineMaxDepth = 4;
|
||||
UPDATE(md, ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);
|
||||
|
||||
// android.scaler
|
||||
const int32_t crop_region[] = {
|
||||
active_array_size.data.i32[0], active_array_size.data.i32[1],
|
||||
|
||||
@@ -283,9 +283,8 @@ ExternalCameraConfig::ExternalCameraConfig() :
|
||||
numVideoBuffers(kDefaultNumVideoBuffer),
|
||||
numStillBuffers(kDefaultNumStillBuffer) {
|
||||
fpsLimits.push_back({/*Size*/{ 640, 480}, /*FPS upper bound*/30.0});
|
||||
fpsLimits.push_back({/*Size*/{1280, 720}, /*FPS upper bound*/15.0});
|
||||
fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/10.0});
|
||||
fpsLimits.push_back({/*Size*/{4096, 3072}, /*FPS upper bound*/5.0});
|
||||
fpsLimits.push_back({/*Size*/{1280, 720}, /*FPS upper bound*/7.5});
|
||||
fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/5.0});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user