diff options
author | Naushir Patuck <naush@raspberrypi.com> | 2022-07-27 09:55:18 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-07-27 18:12:13 +0300 |
commit | acd5d9979fca93bf7a0ffa6f5d08f5cf43ba0cee (patch) | |
tree | b2fb78d222edac459107da0d54991e7a7f5b4dbb /src/ipa/raspberrypi/controller/rpi/agc.cpp | |
parent | 177df04d2b7f357ebe41f1a9809ab68b6f948082 (diff) |
ipa: raspberrypi: Change to C style code comments
As part of the on-going refactor efforts for the source files in
src/ipa/raspberrypi/, switch all C++ style comments to C style comments.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/ipa/raspberrypi/controller/rpi/agc.cpp')
-rw-r--r-- | src/ipa/raspberrypi/controller/rpi/agc.cpp | 269 |
1 files changed, 161 insertions, 108 deletions
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index 52a41a55..5a282a42 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -28,7 +28,7 @@ LOG_DEFINE_CATEGORY(RPiAgc) #define NAME "rpi.agc" -#define PIPELINE_BITS 13 // seems to be a 13-bit pipeline +#define PIPELINE_BITS 13 /* seems to be a 13-bit pipeline */ void AgcMeteringMode::read(boost::property_tree::ptree const ¶ms) { @@ -150,7 +150,7 @@ void AgcConfig::read(boost::property_tree::ptree const ¶ms) convergenceFrames = params.get<unsigned int>("convergence_frames", 6); fastReduceThreshold = params.get<double>("fast_reduce_threshold", 0.4); baseEv = params.get<double>("base_ev", 1.0); - // Start with quite a low value as ramping up is easier than ramping down. + /* Start with quite a low value as ramping up is easier than ramping down. */ defaultExposureTime = params.get<double>("default_exposure_time", 1000) * 1us; defaultAnalogueGain = params.get<double>("default_analogueGain", 1.0); } @@ -170,8 +170,10 @@ Agc::Agc(Controller *controller) maxShutter_(0s), fixedShutter_(0s), fixedAnalogueGain_(0.0) { memset(&awb_, 0, sizeof(awb_)); - // Setting status_.totalExposureValue_ to zero initially tells us - // it's not been calculated yet (i.e. Process hasn't yet run). + /* + * Setting status_.totalExposureValue_ to zero initially tells us + * it's not been calculated yet (i.e. Process hasn't yet run). + */ memset(&status_, 0, sizeof(status_)); status_.ev = ev_; } @@ -185,16 +187,18 @@ void Agc::read(boost::property_tree::ptree const ¶ms) { LOG(RPiAgc, Debug) << "Agc"; config_.read(params); - // Set the config's defaults (which are the first ones it read) as our - // current modes, until someone changes them. (they're all known to - // exist at this point) + /* + * Set the config's defaults (which are the first ones it read) as our + * current modes, until someone changes them. (they're all known to + * exist at this point) + */ meteringModeName_ = config_.defaultMeteringMode; meteringMode_ = &config_.meteringModes[meteringModeName_]; exposureModeName_ = config_.defaultExposureMode; exposureMode_ = &config_.exposureModes[exposureModeName_]; constraintModeName_ = config_.defaultConstraintMode; constraintMode_ = &config_.constraintModes[constraintModeName_]; - // Set up the "last shutter/gain" values, in case AGC starts "disabled". + /* Set up the "last shutter/gain" values, in case AGC starts "disabled". */ status_.shutterTime = config_.defaultExposureTime; status_.analogueGain = config_.defaultAnalogueGain; } @@ -218,8 +222,10 @@ void Agc::resume() unsigned int Agc::getConvergenceFrames() const { - // If shutter and gain have been explicitly set, there is no - // convergence to happen, so no need to drop any frames - return zero. + /* + * If shutter and gain have been explicitly set, there is no + * convergence to happen, so no need to drop any frames - return zero. + */ if (fixedShutter_ && fixedAnalogueGain_) return 0; else @@ -244,14 +250,14 @@ void Agc::setMaxShutter(Duration maxShutter) void Agc::setFixedShutter(Duration fixedShutter) { fixedShutter_ = fixedShutter; - // Set this in case someone calls Pause() straight after. + /* Set this in case someone calls Pause() straight after. */ status_.shutterTime = clipShutter(fixedShutter_); } void Agc::setFixedAnalogueGain(double fixedAnalogueGain) { fixedAnalogueGain_ = fixedAnalogueGain; - // Set this in case someone calls Pause() straight after. + /* Set this in case someone calls Pause() straight after. */ status_.analogueGain = fixedAnalogueGain; } @@ -280,30 +286,32 @@ void Agc::switchMode(CameraMode const &cameraMode, Duration fixedShutter = clipShutter(fixedShutter_); if (fixedShutter && fixedAnalogueGain_) { - // We're going to reset the algorithm here with these fixed values. + /* We're going to reset the algorithm here with these fixed values. */ fetchAwbStatus(metadata); double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 }); ASSERT(minColourGain != 0.0); - // This is the equivalent of computeTargetExposure and applyDigitalGain. + /* This is the equivalent of computeTargetExposure and applyDigitalGain. */ target_.totalExposureNoDG = fixedShutter_ * fixedAnalogueGain_; target_.totalExposure = target_.totalExposureNoDG / minColourGain; - // Equivalent of filterExposure. This resets any "history". + /* Equivalent of filterExposure. This resets any "history". */ filtered_ = target_; - // Equivalent of divideUpExposure. + /* Equivalent of divideUpExposure. */ filtered_.shutter = fixedShutter; filtered_.analogueGain = fixedAnalogueGain_; } else if (status_.totalExposureValue) { - // On a mode switch, various things could happen: - // - the exposure profile might change - // - a fixed exposure or gain might be set - // - the new mode's sensitivity might be different - // We cope with the last of these by scaling the target values. After - // that we just need to re-divide the exposure/gain according to the - // current exposure profile, which takes care of everything else. + /* + * On a mode switch, various things could happen: + * - the exposure profile might change + * - a fixed exposure or gain might be set + * - the new mode's sensitivity might be different + * We cope with the last of these by scaling the target values. After + * that we just need to re-divide the exposure/gain according to the + * current exposure profile, which takes care of everything else. + */ double ratio = lastSensitivity_ / cameraMode.sensitivity; target_.totalExposureNoDG *= ratio; @@ -313,29 +321,31 @@ void Agc::switchMode(CameraMode const &cameraMode, divideUpExposure(); } else { - // We come through here on startup, when at least one of the shutter - // or gain has not been fixed. We must still write those values out so - // that they will be applied immediately. We supply some arbitrary defaults - // for any that weren't set. - - // Equivalent of divideUpExposure. + /* + * We come through here on startup, when at least one of the shutter + * or gain has not been fixed. We must still write those values out so + * that they will be applied immediately. We supply some arbitrary defaults + * for any that weren't set. + */ + + /* Equivalent of divideUpExposure. */ filtered_.shutter = fixedShutter ? fixedShutter : config_.defaultExposureTime; filtered_.analogueGain = fixedAnalogueGain_ ? fixedAnalogueGain_ : config_.defaultAnalogueGain; } writeAndFinish(metadata, false); - // We must remember the sensitivity of this mode for the next SwitchMode. + /* We must remember the sensitivity of this mode for the next SwitchMode. */ lastSensitivity_ = cameraMode.sensitivity; } void Agc::prepare(Metadata *imageMetadata) { status_.digitalGain = 1.0; - fetchAwbStatus(imageMetadata); // always fetch it so that Process knows it's been done + fetchAwbStatus(imageMetadata); /* always fetch it so that Process knows it's been done */ if (status_.totalExposureValue) { - // Process has run, so we have meaningful values. + /* Process has run, so we have meaningful values. */ DeviceStatus deviceStatus; if (imageMetadata->get("device.status", deviceStatus) == 0) { Duration actualExposure = deviceStatus.shutterSpeed * @@ -343,14 +353,16 @@ void Agc::prepare(Metadata *imageMetadata) if (actualExposure) { status_.digitalGain = status_.totalExposureValue / actualExposure; LOG(RPiAgc, Debug) << "Want total exposure " << status_.totalExposureValue; - // Never ask for a gain < 1.0, and also impose - // some upper limit. Make it customisable? + /* + * Never ask for a gain < 1.0, and also impose + * some upper limit. Make it customisable? + */ status_.digitalGain = std::max(1.0, std::min(status_.digitalGain, 4.0)); LOG(RPiAgc, Debug) << "Actual exposure " << actualExposure; LOG(RPiAgc, Debug) << "Use digitalGain " << status_.digitalGain; LOG(RPiAgc, Debug) << "Effective exposure " << actualExposure * status_.digitalGain; - // Decide whether AEC/AGC has converged. + /* Decide whether AEC/AGC has converged. */ updateLockStatus(deviceStatus); } } else @@ -362,44 +374,52 @@ void Agc::prepare(Metadata *imageMetadata) void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata) { frameCount_++; - // First a little bit of housekeeping, fetching up-to-date settings and - // configuration, that kind of thing. + /* + * First a little bit of housekeeping, fetching up-to-date settings and + * configuration, that kind of thing. + */ housekeepConfig(); - // Get the current exposure values for the frame that's just arrived. + /* Get the current exposure values for the frame that's just arrived. */ fetchCurrentExposure(imageMetadata); - // Compute the total gain we require relative to the current exposure. + /* Compute the total gain we require relative to the current exposure. */ double gain, targetY; computeGain(stats.get(), imageMetadata, gain, targetY); - // Now compute the target (final) exposure which we think we want. + /* Now compute the target (final) exposure which we think we want. */ computeTargetExposure(gain); - // Some of the exposure has to be applied as digital gain, so work out - // what that is. This function also tells us whether it's decided to - // "desaturate" the image more quickly. + /* + * Some of the exposure has to be applied as digital gain, so work out + * what that is. This function also tells us whether it's decided to + * "desaturate" the image more quickly. + */ bool desaturate = applyDigitalGain(gain, targetY); - // The results have to be filtered so as not to change too rapidly. + /* The results have to be filtered so as not to change too rapidly. */ filterExposure(desaturate); - // The last thing is to divide up the exposure value into a shutter time - // and analogue gain, according to the current exposure mode. + /* + * The last thing is to divide up the exposure value into a shutter time + * and analogue gain, according to the current exposure mode. + */ divideUpExposure(); - // Finally advertise what we've done. + /* Finally advertise what we've done. */ writeAndFinish(imageMetadata, desaturate); } void Agc::updateLockStatus(DeviceStatus const &deviceStatus) { - const double errorFactor = 0.10; // make these customisable? + const double errorFactor = 0.10; /* make these customisable? */ const int maxLockCount = 5; - // Reset "lock count" when we exceed this multiple of errorFactor + /* Reset "lock count" when we exceed this multiple of errorFactor */ const double resetMargin = 1.5; - // Add 200us to the exposure time error to allow for line quantisation. + /* Add 200us to the exposure time error to allow for line quantisation. */ Duration exposureError = lastDeviceStatus_.shutterSpeed * errorFactor + 200us; double gainError = lastDeviceStatus_.analogueGain * errorFactor; Duration targetError = lastTargetExposure_ * errorFactor; - // Note that we don't know the exposure/gain limits of the sensor, so - // the values we keep requesting may be unachievable. For this reason - // we only insist that we're close to values in the past few frames. + /* + * Note that we don't know the exposure/gain limits of the sensor, so + * the values we keep requesting may be unachievable. For this reason + * we only insist that we're close to values in the past few frames. + */ if (deviceStatus.shutterSpeed > lastDeviceStatus_.shutterSpeed - exposureError && deviceStatus.shutterSpeed < lastDeviceStatus_.shutterSpeed + exposureError && deviceStatus.analogueGain > lastDeviceStatus_.analogueGain - gainError && @@ -430,7 +450,7 @@ static void copyString(std::string const &s, char *d, size_t size) void Agc::housekeepConfig() { - // First fetch all the up-to-date settings, so no one else has to do it. + /* First fetch all the up-to-date settings, so no one else has to do it. */ status_.ev = ev_; status_.fixedShutter = clipShutter(fixedShutter_); status_.fixedAnalogueGain = fixedAnalogueGain_; @@ -438,8 +458,10 @@ void Agc::housekeepConfig() LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixedShutter " << status_.fixedShutter << " fixedAnalogueGain " << status_.fixedAnalogueGain; - // Make sure the "mode" pointers point to the up-to-date things, if - // they've changed. + /* + * Make sure the "mode" pointers point to the up-to-date things, if + * they've changed. + */ if (strcmp(meteringModeName_.c_str(), status_.meteringMode)) { auto it = config_.meteringModes.find(meteringModeName_); if (it == config_.meteringModes.end()) @@ -491,7 +513,7 @@ void Agc::fetchCurrentExposure(Metadata *imageMetadata) void Agc::fetchAwbStatus(Metadata *imageMetadata) { - awb_.gainR = 1.0; // in case not found in metadata + awb_.gainR = 1.0; /* in case not found in metadata */ awb_.gainG = 1.0; awb_.gainB = 1.0; if (imageMetadata->get("awb.status", awb_) != 0) @@ -502,8 +524,10 @@ static double computeInitialY(bcm2835_isp_stats *stats, AwbStatus const &awb, double weights[], double gain) { bcm2835_isp_stats_region *regions = stats->agc_stats; - // Note how the calculation below means that equal weights give you - // "average" metering (i.e. all pixels equally important). + /* + * Note how the calculation below means that equal weights give you + * "average" metering (i.e. all pixels equally important). + */ double rSum = 0, gSum = 0, bSum = 0, pixelSum = 0; for (int i = 0; i < AGC_STATS_SIZE; i++) { double counted = regions[i].counted; @@ -525,11 +549,13 @@ static double computeInitialY(bcm2835_isp_stats *stats, AwbStatus const &awb, return ySum / pixelSum / (1 << PIPELINE_BITS); } -// We handle extra gain through EV by adjusting our Y targets. However, you -// simply can't monitor histograms once they get very close to (or beyond!) -// saturation, so we clamp the Y targets to this value. It does mean that EV -// increases don't necessarily do quite what you might expect in certain -// (contrived) cases. +/* + * We handle extra gain through EV by adjusting our Y targets. However, you + * simply can't monitor histograms once they get very close to (or beyond!) + * saturation, so we clamp the Y targets to this value. It does mean that EV + * increases don't necessarily do quite what you might expect in certain + * (contrived) cases. + */ #define EV_GAIN_Y_TARGET_LIMIT 0.9 @@ -546,18 +572,22 @@ void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *imageMetadata, double &gain, double &targetY) { struct LuxStatus lux = {}; - lux.lux = 400; // default lux level to 400 in case no metadata found + lux.lux = 400; /* default lux level to 400 in case no metadata found */ if (imageMetadata->get("lux.status", lux) != 0) LOG(RPiAgc, Warning) << "Agc: no lux level found"; Histogram h(statistics->hist[0].g_hist, NUM_HISTOGRAM_BINS); double evGain = status_.ev * config_.baseEv; - // The initial gain and target_Y come from some of the regions. After - // that we consider the histogram constraints. + /* + * The initial gain and target_Y come from some of the regions. After + * that we consider the histogram constraints. + */ targetY = config_.yTarget.eval(config_.yTarget.domain().clip(lux.lux)); targetY = std::min(EV_GAIN_Y_TARGET_LIMIT, targetY * evGain); - // Do this calculation a few times as brightness increase can be - // non-linear when there are saturated regions. + /* + * Do this calculation a few times as brightness increase can be + * non-linear when there are saturated regions. + */ gain = 1.0; for (int i = 0; i < 8; i++) { double initialY = computeInitialY(statistics, awb_, meteringMode_->weights, gain); @@ -565,7 +595,7 @@ void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *imageMetadata, gain *= extraGain; LOG(RPiAgc, Debug) << "Initial Y " << initialY << " target " << targetY << " gives gain " << gain; - if (extraGain < 1.01) // close enough + if (extraGain < 1.01) /* close enough */ break; } @@ -592,20 +622,23 @@ void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *imageMetadata, void Agc::computeTargetExposure(double gain) { if (status_.fixedShutter && status_.fixedAnalogueGain) { - // When ag and shutter are both fixed, we need to drive the - // total exposure so that we end up with a digital gain of at least - // 1/minColourGain. Otherwise we'd desaturate channels causing - // white to go cyan or magenta. + /* + * When ag and shutter are both fixed, we need to drive the + * total exposure so that we end up with a digital gain of at least + * 1/minColourGain. Otherwise we'd desaturate channels causing + * white to go cyan or magenta. + */ double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 }); ASSERT(minColourGain != 0.0); target_.totalExposure = status_.fixedShutter * status_.fixedAnalogueGain / minColourGain; } else { - // The statistics reflect the image without digital gain, so the final - // total exposure we're aiming for is: + /* + * The statistics reflect the image without digital gain, so the final + * total exposure we're aiming for is: + */ target_.totalExposure = current_.totalExposureNoDG * gain; - // The final target exposure is also limited to what the exposure - // mode allows. + /* The final target exposure is also limited to what the exposure mode allows. */ Duration maxShutter = status_.fixedShutter ? status_.fixedShutter : exposureMode_->shutter.back(); @@ -625,17 +658,21 @@ bool Agc::applyDigitalGain(double gain, double targetY) double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 }); ASSERT(minColourGain != 0.0); double dg = 1.0 / minColourGain; - // I think this pipeline subtracts black level and rescales before we - // get the stats, so no need to worry about it. + /* + * I think this pipeline subtracts black level and rescales before we + * get the stats, so no need to worry about it. + */ LOG(RPiAgc, Debug) << "after AWB, target dg " << dg << " gain " << gain << " target_Y " << targetY; - // Finally, if we're trying to reduce exposure but the target_Y is - // "close" to 1.0, then the gain computed for that constraint will be - // only slightly less than one, because the measured Y can never be - // larger than 1.0. When this happens, demand a large digital gain so - // that the exposure can be reduced, de-saturating the image much more - // quickly (and we then approach the correct value more quickly from - // below). + /* + * Finally, if we're trying to reduce exposure but the target_Y is + * "close" to 1.0, then the gain computed for that constraint will be + * only slightly less than one, because the measured Y can never be + * larger than 1.0. When this happens, demand a large digital gain so + * that the exposure can be reduced, de-saturating the image much more + * quickly (and we then approach the correct value more quickly from + * below). + */ bool desaturate = targetY > config_.fastReduceThreshold && gain < sqrt(targetY); if (desaturate) @@ -649,8 +686,10 @@ bool Agc::applyDigitalGain(double gain, double targetY) void Agc::filterExposure(bool desaturate) { double speed = config_.speed; - // AGC adapts instantly if both shutter and gain are directly specified - // or we're in the startup phase. + /* + * AGC adapts instantly if both shutter and gain are directly specified + * or we're in the startup phase. + */ if ((status_.fixedShutter && status_.fixedAnalogueGain) || frameCount_ <= config_.startupFrames) speed = 1.0; @@ -658,15 +697,19 @@ void Agc::filterExposure(bool desaturate) filtered_.totalExposure = target_.totalExposure; filtered_.totalExposureNoDG = target_.totalExposureNoDG; } else { - // If close to the result go faster, to save making so many - // micro-adjustments on the way. (Make this customisable?) + /* + * If close to the result go faster, to save making so many + * micro-adjustments on the way. (Make this customisable?) + */ if (filtered_.totalExposure < 1.2 * target_.totalExposure && filtered_.totalExposure > 0.8 * target_.totalExposure) speed = sqrt(speed); filtered_.totalExposure = speed * target_.totalExposure + filtered_.totalExposure * (1.0 - speed); - // When desaturing, take a big jump down in totalExposureNoDG, - // which we'll hide with digital gain. + /* + * When desaturing, take a big jump down in totalExposureNoDG, + * which we'll hide with digital gain. + */ if (desaturate) filtered_.totalExposureNoDG = target_.totalExposureNoDG; @@ -675,9 +718,11 @@ void Agc::filterExposure(bool desaturate) speed * target_.totalExposureNoDG + filtered_.totalExposureNoDG * (1.0 - speed); } - // We can't let the totalExposureNoDG exposure deviate too far below the - // total exposure, as there might not be enough digital gain available - // in the ISP to hide it (which will cause nasty oscillation). + /* + * We can't let the totalExposureNoDG exposure deviate too far below the + * total exposure, as there might not be enough digital gain available + * in the ISP to hide it (which will cause nasty oscillation). + */ if (filtered_.totalExposureNoDG < filtered_.totalExposure * config_.fastReduceThreshold) filtered_.totalExposureNoDG = filtered_.totalExposure * config_.fastReduceThreshold; @@ -687,9 +732,11 @@ void Agc::filterExposure(bool desaturate) void Agc::divideUpExposure() { - // Sending the fixed shutter/gain cases through the same code may seem - // unnecessary, but it will make more sense when extend this to cover - // variable aperture. + /* + * Sending the fixed shutter/gain cases through the same code may seem + * unnecessary, but it will make more sense when extend this to cover + * variable aperture. + */ Duration exposureValue = filtered_.totalExposureNoDG; Duration shutterTime; double analogueGain; @@ -721,18 +768,22 @@ void Agc::divideUpExposure() } LOG(RPiAgc, Debug) << "Divided up shutter and gain are " << shutterTime << " and " << analogueGain; - // Finally adjust shutter time for flicker avoidance (require both - // shutter and gain not to be fixed). + /* + * Finally adjust shutter time for flicker avoidance (require both + * shutter and gain not to be fixed). + */ if (!status_.fixedShutter && !status_.fixedAnalogueGain && status_.flickerPeriod) { int flickerPeriods = shutterTime / status_.flickerPeriod; if (flickerPeriods) { Duration newShutterTime = flickerPeriods * status_.flickerPeriod; analogueGain *= shutterTime / newShutterTime; - // We should still not allow the ag to go over the - // largest value in the exposure mode. Note that this - // may force more of the total exposure into the digital - // gain as a side-effect. + /* + * We should still not allow the ag to go over the + * largest value in the exposure mode. Note that this + * may force more of the total exposure into the digital + * gain as a side-effect. + */ analogueGain = std::min(analogueGain, exposureMode_->gain.back()); shutterTime = newShutterTime; } @@ -749,8 +800,10 @@ void Agc::writeAndFinish(Metadata *imageMetadata, bool desaturate) status_.targetExposureValue = desaturate ? 0s : target_.totalExposureNoDG; status_.shutterTime = filtered_.shutter; status_.analogueGain = filtered_.analogueGain; - // Write to metadata as well, in case anyone wants to update the camera - // immediately. + /* + * Write to metadata as well, in case anyone wants to update the camera + * immediately. + */ imageMetadata->set("agc.status", status_); LOG(RPiAgc, Debug) << "Output written, total exposure requested is " << filtered_.totalExposure; @@ -765,7 +818,7 @@ Duration Agc::clipShutter(Duration shutter) return shutter; } -// Register algorithm with the system. +/* Register algorithm with the system. */ static Algorithm *create(Controller *controller) { return (Algorithm *)new Agc(controller); |