pipeline: ipa: raspberrypi: Pass controls to IPA on start
Forward any controls passed into the pipeline handler to the IPA. The IPA then sets up the Raspberry Pi controller with these settings appropriately, and passes back any V4L2 sensor controls that need to be applied. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Tested-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
0238b9e080
commit
2795f333fc
3 changed files with 47 additions and 20 deletions
|
@ -22,6 +22,7 @@ enum ConfigParameters {
|
||||||
IPA_CONFIG_SENSOR = (1 << 2),
|
IPA_CONFIG_SENSOR = (1 << 2),
|
||||||
IPA_CONFIG_DROP_FRAMES = (1 << 3),
|
IPA_CONFIG_DROP_FRAMES = (1 << 3),
|
||||||
IPA_CONFIG_FAILED = (1 << 4),
|
IPA_CONFIG_FAILED = (1 << 4),
|
||||||
|
IPA_CONFIG_STARTUP = (1 << 5),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Operations {
|
enum Operations {
|
||||||
|
|
|
@ -78,8 +78,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int init(const IPASettings &settings) override;
|
int init(const IPASettings &settings) override;
|
||||||
int start([[maybe_unused]] const IPAOperationData &data,
|
int start(const IPAOperationData &data, IPAOperationData *result) override;
|
||||||
[[maybe_unused]] IPAOperationData *result) override { return 0; }
|
|
||||||
void stop() override {}
|
void stop() override {}
|
||||||
|
|
||||||
void configure(const CameraSensorInfo &sensorInfo,
|
void configure(const CameraSensorInfo &sensorInfo,
|
||||||
|
@ -154,6 +153,36 @@ int IPARPi::init(const IPASettings &settings)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IPARPi::start(const IPAOperationData &data, IPAOperationData *result)
|
||||||
|
{
|
||||||
|
RPiController::Metadata metadata;
|
||||||
|
|
||||||
|
ASSERT(result);
|
||||||
|
result->operation = 0;
|
||||||
|
if (data.operation & RPi::IPA_CONFIG_STARTUP) {
|
||||||
|
/* We have been given some controls to action before start. */
|
||||||
|
queueRequest(data.controls[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
controller_.SwitchMode(mode_, &metadata);
|
||||||
|
|
||||||
|
/* SwitchMode may supply updated exposure/gain values to use. */
|
||||||
|
AgcStatus agcStatus;
|
||||||
|
agcStatus.shutter_time = 0.0;
|
||||||
|
agcStatus.analogue_gain = 0.0;
|
||||||
|
|
||||||
|
/* SwitchMode may supply updated exposure/gain values to use. */
|
||||||
|
metadata.Get("agc.status", agcStatus);
|
||||||
|
if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) {
|
||||||
|
ControlList ctrls(unicamCtrls_);
|
||||||
|
applyAGC(&agcStatus, ctrls);
|
||||||
|
result->controls.emplace_back(ctrls);
|
||||||
|
result->operation |= RPi::IPA_CONFIG_SENSOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void IPARPi::setMode(const CameraSensorInfo &sensorInfo)
|
void IPARPi::setMode(const CameraSensorInfo &sensorInfo)
|
||||||
{
|
{
|
||||||
mode_.bitdepth = sensorInfo.bitsPerPixel;
|
mode_.bitdepth = sensorInfo.bitsPerPixel;
|
||||||
|
@ -295,11 +324,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
|
||||||
result->data.push_back(dropFrame);
|
result->data.push_back(dropFrame);
|
||||||
result->operation |= RPi::IPA_CONFIG_DROP_FRAMES;
|
result->operation |= RPi::IPA_CONFIG_DROP_FRAMES;
|
||||||
|
|
||||||
/* These zero values mean not program anything (unless overwritten). */
|
|
||||||
struct AgcStatus agcStatus;
|
|
||||||
agcStatus.shutter_time = 0.0;
|
|
||||||
agcStatus.analogue_gain = 0.0;
|
|
||||||
|
|
||||||
if (!controllerInit_) {
|
if (!controllerInit_) {
|
||||||
/* Load the tuning file for this sensor. */
|
/* Load the tuning file for this sensor. */
|
||||||
controller_.Read(tuningFile_.c_str());
|
controller_.Read(tuningFile_.c_str());
|
||||||
|
@ -307,20 +331,13 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
|
||||||
controllerInit_ = true;
|
controllerInit_ = true;
|
||||||
|
|
||||||
/* Supply initial values for gain and exposure. */
|
/* Supply initial values for gain and exposure. */
|
||||||
|
ControlList ctrls(unicamCtrls_);
|
||||||
|
AgcStatus agcStatus;
|
||||||
agcStatus.shutter_time = DefaultExposureTime;
|
agcStatus.shutter_time = DefaultExposureTime;
|
||||||
agcStatus.analogue_gain = DefaultAnalogueGain;
|
agcStatus.analogue_gain = DefaultAnalogueGain;
|
||||||
}
|
|
||||||
|
|
||||||
RPiController::Metadata metadata;
|
|
||||||
controller_.SwitchMode(mode_, &metadata);
|
|
||||||
|
|
||||||
/* SwitchMode may supply updated exposure/gain values to use. */
|
|
||||||
metadata.Get("agc.status", agcStatus);
|
|
||||||
if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) {
|
|
||||||
ControlList ctrls(unicamCtrls_);
|
|
||||||
applyAGC(&agcStatus, ctrls);
|
applyAGC(&agcStatus, ctrls);
|
||||||
result->controls.push_back(ctrls);
|
|
||||||
|
|
||||||
|
result->controls.emplace_back(ctrls);
|
||||||
result->operation |= RPi::IPA_CONFIG_SENSOR;
|
result->operation |= RPi::IPA_CONFIG_SENSOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +851,7 @@ void IPARPi::processStats(unsigned int bufferId)
|
||||||
|
|
||||||
IPAOperationData op;
|
IPAOperationData op;
|
||||||
op.operation = RPi::IPA_ACTION_V4L2_SET_STAGGERED;
|
op.operation = RPi::IPA_ACTION_V4L2_SET_STAGGERED;
|
||||||
op.controls.push_back(ctrls);
|
op.controls.emplace_back(ctrls);
|
||||||
queueFrameAction.emit(0, op);
|
queueFrameAction.emit(0, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -754,8 +754,10 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
|
||||||
/* Start the IPA. */
|
/* Start the IPA. */
|
||||||
IPAOperationData ipaData = {};
|
IPAOperationData ipaData = {};
|
||||||
IPAOperationData result = {};
|
IPAOperationData result = {};
|
||||||
if (controls)
|
if (controls) {
|
||||||
|
ipaData.operation = RPi::IPA_CONFIG_STARTUP;
|
||||||
ipaData.controls.emplace_back(*controls);
|
ipaData.controls.emplace_back(*controls);
|
||||||
|
}
|
||||||
ret = data->ipa_->start(ipaData, &result);
|
ret = data->ipa_->start(ipaData, &result);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG(RPI, Error)
|
LOG(RPI, Error)
|
||||||
|
@ -764,6 +766,14 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Apply any gain/exposure settings that the IPA may have passed back. */
|
||||||
|
ASSERT(data->staggeredCtrl_);
|
||||||
|
if (result.operation & RPi::IPA_CONFIG_SENSOR) {
|
||||||
|
const ControlList &ctrls = result.controls[0];
|
||||||
|
if (!data->staggeredCtrl_.set(ctrls))
|
||||||
|
LOG(RPI, Error) << "V4L2 staggered set failed";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPA configure may have changed the sensor flips - hence the bayer
|
* IPA configure may have changed the sensor flips - hence the bayer
|
||||||
* order. Get the sensor format and set the ISP input now.
|
* order. Get the sensor format and set the ISP input now.
|
||||||
|
@ -784,7 +794,6 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
|
||||||
* starting. First check that the staggered ctrl has been initialised
|
* starting. First check that the staggered ctrl has been initialised
|
||||||
* by configure().
|
* by configure().
|
||||||
*/
|
*/
|
||||||
ASSERT(data->staggeredCtrl_);
|
|
||||||
data->staggeredCtrl_.reset();
|
data->staggeredCtrl_.reset();
|
||||||
data->staggeredCtrl_.write();
|
data->staggeredCtrl_.write();
|
||||||
data->expectedSequence_ = 0;
|
data->expectedSequence_ = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue