Camera: use rational/double for external camera framerate
For better precision. Ex: minFrameDuration of 30fps 333333334->333333333 Bug: 72261912 Change-Id: I830d694d34eb01426e46279c4c986d8879b9d847
This commit is contained in:
parent
1798249b8f
commit
134093a43f
4 changed files with 33 additions and 18 deletions
|
@ -595,16 +595,19 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
|
|||
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
|
||||
}
|
||||
|
||||
int64_t min_frame_duration = std::numeric_limits<int64_t>::max();
|
||||
for (const auto& frameRate : supportedFormat.frameRates) {
|
||||
int64_t frame_duration = 1000000000LL / frameRate;
|
||||
if (frame_duration < min_frame_duration) {
|
||||
min_frame_duration = frame_duration;
|
||||
int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
|
||||
for (const auto& fr : supportedFormat.frameRates) {
|
||||
// 1000000000LL < (2^32 - 1) and
|
||||
// fr.durationNumerator is uint32_t, so no overflow here
|
||||
int64_t frameDuration = 1000000000LL * fr.durationNumerator /
|
||||
fr.durationDenominator;
|
||||
if (frameDuration < minFrameDuration) {
|
||||
minFrameDuration = frameDuration;
|
||||
}
|
||||
if (frame_duration > maxFrameDuration) {
|
||||
maxFrameDuration = frame_duration;
|
||||
if (frameDuration > maxFrameDuration) {
|
||||
maxFrameDuration = frameDuration;
|
||||
}
|
||||
int32_t frameRateInt = static_cast<int32_t>(frameRate);
|
||||
int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
|
||||
if (minFps > frameRateInt) {
|
||||
minFps = frameRateInt;
|
||||
}
|
||||
|
@ -618,7 +621,7 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
|
|||
minFrameDurations.push_back(format);
|
||||
minFrameDurations.push_back(supportedFormat.width);
|
||||
minFrameDurations.push_back(supportedFormat.height);
|
||||
minFrameDurations.push_back(min_frame_duration);
|
||||
minFrameDurations.push_back(minFrameDuration);
|
||||
}
|
||||
|
||||
// The stall duration is 0 for non-jpeg formats. For JPEG format, stall
|
||||
|
@ -705,8 +708,10 @@ void ExternalCameraDevice::getFrameRateList(
|
|||
++frameInterval.index) {
|
||||
if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||
if (frameInterval.discrete.numerator != 0) {
|
||||
float framerate = frameInterval.discrete.denominator /
|
||||
static_cast<float>(frameInterval.discrete.numerator);
|
||||
SupportedV4L2Format::FrameRate fr = {
|
||||
frameInterval.discrete.numerator,
|
||||
frameInterval.discrete.denominator};
|
||||
double framerate = fr.getDouble();
|
||||
if (framerate > fpsUpperBound) {
|
||||
continue;
|
||||
}
|
||||
|
@ -717,7 +722,7 @@ void ExternalCameraDevice::getFrameRateList(
|
|||
(frameInterval.pixel_format >> 16) & 0xFF,
|
||||
(frameInterval.pixel_format >> 24) & 0xFF,
|
||||
frameInterval.width, frameInterval.height, framerate);
|
||||
format->frameRates.push_back(framerate);
|
||||
format->frameRates.push_back(fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1904,7 +1904,8 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Fo
|
|||
float fps = 1000.f;
|
||||
const float kDefaultFps = 30.f;
|
||||
// Try to pick the slowest fps that is at least 30
|
||||
for (const auto& f : v4l2Fmt.frameRates) {
|
||||
for (const auto& fr : v4l2Fmt.frameRates) {
|
||||
double f = fr.getDouble();
|
||||
if (maxFps < f) {
|
||||
maxFps = f;
|
||||
}
|
||||
|
@ -2346,8 +2347,8 @@ status_t ExternalCameraDeviceSession::initDefaultRequests() {
|
|||
bool support30Fps = false;
|
||||
int32_t maxFps = std::numeric_limits<int32_t>::min();
|
||||
for (const auto& supportedFormat : mSupportedFormats) {
|
||||
for (const auto& frameRate : supportedFormat.frameRates) {
|
||||
int32_t framerateInt = static_cast<int32_t>(frameRate);
|
||||
for (const auto& fr : supportedFormat.frameRates) {
|
||||
int32_t framerateInt = static_cast<int32_t>(fr.getDouble());
|
||||
if (maxFps < framerateInt) {
|
||||
maxFps = framerateInt;
|
||||
}
|
||||
|
|
|
@ -147,6 +147,10 @@ bool isAspectRatioClose(float ar1, float ar2) {
|
|||
return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
|
||||
}
|
||||
|
||||
double SupportedV4L2Format::FrameRate::getDouble() const {
|
||||
return durationDenominator / static_cast<double>(durationNumerator);
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V3_4
|
||||
} // namespace device
|
||||
|
@ -247,7 +251,7 @@ ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
|
|||
limit.size = {
|
||||
row->UnsignedAttribute("width", /*Default*/0),
|
||||
row->UnsignedAttribute("height", /*Default*/0)};
|
||||
limit.fpsUpperBound = row->FloatAttribute("fpsBound", /*Default*/1000.0);
|
||||
limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/1000.0);
|
||||
if (limit.size.width <= prevLimit.size.width ||
|
||||
limit.size.height <= prevLimit.size.height ||
|
||||
limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
|
||||
|
|
|
@ -73,7 +73,7 @@ struct ExternalCameraConfig {
|
|||
|
||||
struct FpsLimitation {
|
||||
Size size;
|
||||
float fpsUpperBound;
|
||||
double fpsUpperBound;
|
||||
};
|
||||
std::vector<FpsLimitation> fpsLimits;
|
||||
|
||||
|
@ -93,7 +93,12 @@ struct SupportedV4L2Format {
|
|||
uint32_t height;
|
||||
uint32_t fourcc;
|
||||
// All supported frame rate for this w/h/fourcc combination
|
||||
std::vector<float> frameRates;
|
||||
struct FrameRate {
|
||||
uint32_t durationNumerator; // frame duration numerator. Ex: 1
|
||||
uint32_t durationDenominator; // frame duration denominator. Ex: 30
|
||||
double getDouble() const; // FrameRate in double. Ex: 30.0
|
||||
};
|
||||
std::vector<FrameRate> frameRates;
|
||||
};
|
||||
|
||||
// A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)
|
||||
|
|
Loading…
Reference in a new issue