libcamera: ipu3: Remove streams from generateConfiguration

Remove stream assignment from the IPU3 pipeline handler
generateConfiguration() implementation.

The function aims to provide a suitable default for the requested use
cases. Defer stream assignment to validation and only initialize sizes
and formats.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Jacopo Mondi 2020-06-29 11:38:48 +02:00
parent dd0793ed1b
commit ed98a81fc3

View file

@ -31,6 +31,15 @@ namespace libcamera {
LOG_DEFINE_CATEGORY(IPU3) LOG_DEFINE_CATEGORY(IPU3)
static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
static constexpr unsigned int IPU3_MAX_STREAMS = 3;
static const Size IMGU_OUTPUT_MIN_SIZE = { 2, 2 };
static const Size IMGU_OUTPUT_MAX_SIZE = { 4480, 34004 };
static constexpr unsigned int IMGU_OUTPUT_WIDTH_ALIGN = 64;
static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;
static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;
static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;
class IPU3CameraData : public CameraData class IPU3CameraData : public CameraData
{ {
public: public:
@ -61,9 +70,6 @@ public:
const std::vector<const Stream *> &streams() { return streams_; } const std::vector<const Stream *> &streams() { return streams_; }
private: private:
static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
static constexpr unsigned int IPU3_MAX_STREAMS = 3;
void assignStreams(); void assignStreams();
void adjustStream(StreamConfiguration &cfg, bool scale); void adjustStream(StreamConfiguration &cfg, bool scale);
@ -299,94 +305,50 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
{ {
IPU3CameraData *data = cameraData(camera); IPU3CameraData *data = cameraData(camera);
IPU3CameraConfiguration *config = new IPU3CameraConfiguration(camera, data); IPU3CameraConfiguration *config = new IPU3CameraConfiguration(camera, data);
std::set<Stream *> streams = {
&data->outStream_,
&data->vfStream_,
&data->rawStream_,
};
if (roles.empty()) if (roles.empty())
return config; return config;
Size sensorResolution = data->cio2_.sensor()->resolution();
for (const StreamRole role : roles) { for (const StreamRole role : roles) {
StreamConfiguration cfg = {}; StreamConfiguration cfg = {};
Stream *stream = nullptr;
cfg.pixelFormat = formats::NV12;
switch (role) { switch (role) {
case StreamRole::StillCapture: case StreamRole::StillCapture:
/* /*
* Pick the output stream by default as the Viewfinder * Use as default full-frame configuration a value
* and VideoRecording roles are not allowed on * strictly smaller than the sensor resolution (limited
* the output stream. * to the ImgU maximum output size) and aligned down to
* the required frame margin.
*/ */
if (streams.find(&data->outStream_) != streams.end()) { cfg.size = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE);
stream = &data->outStream_; cfg.size.width = utils::alignDown(cfg.size.width - 1,
} else if (streams.find(&data->vfStream_) != streams.end()) { IMGU_OUTPUT_WIDTH_MARGIN);
stream = &data->vfStream_; cfg.size.height = utils::alignDown(cfg.size.height - 1,
} else { IMGU_OUTPUT_HEIGHT_MARGIN);
LOG(IPU3, Error) cfg.pixelFormat = formats::NV12;
<< "No stream available for requested role " cfg.bufferCount = IPU3_BUFFER_COUNT;
<< role;
break;
}
/*
* FIXME: Soraka: the maximum resolution reported by
* both sensors (2592x1944 for ov5670 and 4224x3136 for
* ov13858) are returned as default configurations but
* they're not correctly processed by the ImgU.
* Resolutions up tp 2560x1920 have been validated.
*
* \todo Clarify ImgU alignment requirements.
*/
cfg.size = { 2560, 1920 };
break; break;
case StreamRole::StillCaptureRaw: { case StreamRole::StillCaptureRaw: {
if (streams.find(&data->rawStream_) == streams.end()) { cfg = data->cio2_.generateConfiguration(sensorResolution);
LOG(IPU3, Error)
<< "Multiple raw streams are not supported";
break;
}
stream = &data->rawStream_;
cfg.size = data->cio2_.sensor()->resolution();
cfg = data->cio2_.generateConfiguration(cfg.size);
break; break;
} }
case StreamRole::Viewfinder: case StreamRole::Viewfinder:
case StreamRole::VideoRecording: { case StreamRole::VideoRecording: {
/* /*
* We can't use the 'output' stream for viewfinder or * Default viewfinder and videorecording to 1280x720,
* video capture roles. * capped to the maximum sensor resolution and aligned
* * to the ImgU output constraints.
* \todo This is an artificial limitation until we
* figure out the exact capabilities of the hardware.
*/ */
if (streams.find(&data->vfStream_) == streams.end()) { cfg.size = sensorResolution.boundedTo({ 1280, 720 })
LOG(IPU3, Error) .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN,
<< "No stream available for requested role " IMGU_OUTPUT_HEIGHT_ALIGN);
<< role; cfg.pixelFormat = formats::NV12;
break; cfg.bufferCount = IPU3_BUFFER_COUNT;
}
stream = &data->vfStream_;
/*
* Align the default viewfinder size to the maximum
* available sensor resolution and to the IPU3
* alignment constraints.
*/
const Size &res = data->cio2_.sensor()->resolution();
unsigned int width = std::min(1280U, res.width);
unsigned int height = std::min(720U, res.height);
cfg.size = { width & ~7, height & ~3 };
break; break;
} }
@ -394,16 +356,10 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
default: default:
LOG(IPU3, Error) LOG(IPU3, Error)
<< "Requested stream role not supported: " << role; << "Requested stream role not supported: " << role;
break;
}
if (!stream) {
delete config; delete config;
return nullptr; return nullptr;
} }
streams.erase(stream);
config->addConfiguration(cfg); config->addConfiguration(cfg);
} }