libcamera: Switch to CameraConfiguration

Implement the camera configuration thru out the library, tests, cam and
qcam tools.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Niklas Söderlund 2019-04-05 02:52:59 +02:00
parent 9a7dc3ce7f
commit b0c730e330
16 changed files with 54 additions and 81 deletions

View file

@ -73,9 +73,9 @@ public:
int release(); int release();
const std::set<Stream *> &streams() const; const std::set<Stream *> &streams() const;
std::map<Stream *, StreamConfiguration> CameraConfiguration
streamConfiguration(const std::vector<StreamUsage> &usage); streamConfiguration(const std::vector<StreamUsage> &usage);
int configureStreams(std::map<Stream *, StreamConfiguration> &config); int configureStreams(const CameraConfiguration &config);
int allocateBuffers(); int allocateBuffers();
int freeBuffers(); int freeBuffers();

View file

@ -78,10 +78,10 @@ static int parseOptions(int argc, char *argv[])
return 0; return 0;
} }
static int prepareCameraConfig(std::map<Stream *, StreamConfiguration> *config) static int prepareCameraConfig(CameraConfiguration *config)
{ {
*config = camera->streamConfiguration({ Stream::VideoRecording() }); *config = camera->streamConfiguration({ Stream::VideoRecording() });
Stream *stream = config->begin()->first; Stream *stream = config->front();
if (options.isSet(OptFormat)) { if (options.isSet(OptFormat)) {
KeyValueParser::Options format = options[OptFormat]; KeyValueParser::Options format = options[OptFormat];
@ -135,7 +135,7 @@ static void requestComplete(Request *request, const std::map<Stream *, Buffer *>
static int capture() static int capture()
{ {
std::map<Stream *, StreamConfiguration> config; CameraConfiguration config;
std::vector<Request *> requests; std::vector<Request *> requests;
int ret; int ret;
@ -151,7 +151,7 @@ static int capture()
return ret; return ret;
} }
Stream *stream = config.begin()->first; Stream *stream = config.front();
ret = camera->allocateBuffers(); ret = camera->allocateBuffers();
if (ret) { if (ret) {

View file

@ -543,21 +543,21 @@ const std::set<Stream *> &Camera::streams() const
* list of stream usages and the camera returns a map of suitable streams and * list of stream usages and the camera returns a map of suitable streams and
* their suggested default configurations. * their suggested default configurations.
* *
* \return A map of streams to configurations if the requested usages can be * \return A valid CameraConfiguration if the requested usages can be satisfied,
* satisfied, or an empty map otherwise * or a invalid one otherwise
*/ */
std::map<Stream *, StreamConfiguration> CameraConfiguration
Camera::streamConfiguration(const std::vector<StreamUsage> &usages) Camera::streamConfiguration(const std::vector<StreamUsage> &usages)
{ {
if (disconnected_ || !usages.size() || usages.size() > streams_.size()) if (disconnected_ || !usages.size() || usages.size() > streams_.size())
return std::map<Stream *, StreamConfiguration>{}; return CameraConfiguration();
return pipe_->streamConfiguration(this, usages); return pipe_->streamConfiguration(this, usages);
} }
/** /**
* \brief Configure the camera's streams prior to capture * \brief Configure the camera's streams prior to capture
* \param[in] config A map of stream IDs and configurations to setup * \param[in] config The camera configurations to setup
* *
* Prior to starting capture, the camera must be configured to select a * Prior to starting capture, the camera must be configured to select a
* group of streams to be involved in the capture and their configuration. * group of streams to be involved in the capture and their configuration.
@ -579,7 +579,7 @@ Camera::streamConfiguration(const std::vector<StreamUsage> &usages)
* \retval -EACCES The camera is not in a state where it can be configured * \retval -EACCES The camera is not in a state where it can be configured
* \retval -EINVAL The configuration is not valid * \retval -EINVAL The configuration is not valid
*/ */
int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config) int Camera::configureStreams(const CameraConfiguration &config)
{ {
int ret; int ret;
@ -589,14 +589,14 @@ int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config)
if (!stateBetween(CameraAcquired, CameraConfigured)) if (!stateBetween(CameraAcquired, CameraConfigured))
return -EACCES; return -EACCES;
if (!config.size()) { if (!config.isValid()) {
LOG(Camera, Error) LOG(Camera, Error)
<< "Can't configure streams without a configuration"; << "Can't configure camera with invalid configuration";
return -EINVAL; return -EINVAL;
} }
for (auto const &iter : config) { for (Stream *stream : config) {
if (streams_.find(iter.first) == streams_.end()) if (streams_.find(stream) == streams_.end())
return -EINVAL; return -EINVAL;
} }
@ -605,9 +605,8 @@ int Camera::configureStreams(std::map<Stream *, StreamConfiguration> &config)
return ret; return ret;
activeStreams_.clear(); activeStreams_.clear();
for (auto const &iter : config) { for (Stream *stream : config) {
Stream *stream = iter.first; const StreamConfiguration &cfg = config[stream];
const StreamConfiguration &cfg = iter.second;
stream->configuration_ = cfg; stream->configuration_ = cfg;
activeStreams_.insert(stream); activeStreams_.insert(stream);

View file

@ -18,6 +18,7 @@ namespace libcamera {
class Buffer; class Buffer;
class BufferPool; class BufferPool;
class Camera; class Camera;
class CameraConfiguration;
class CameraManager; class CameraManager;
class DeviceEnumerator; class DeviceEnumerator;
class MediaDevice; class MediaDevice;
@ -52,10 +53,9 @@ public:
virtual bool match(DeviceEnumerator *enumerator) = 0; virtual bool match(DeviceEnumerator *enumerator) = 0;
virtual std::map<Stream *, StreamConfiguration> virtual CameraConfiguration
streamConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) = 0; streamConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) = 0;
virtual int configureStreams(Camera *camera, virtual int configureStreams(Camera *camera, const CameraConfiguration &config) = 0;
std::map<Stream *, StreamConfiguration> &config) = 0;
virtual int allocateBuffers(Camera *camera, Stream *stream) = 0; virtual int allocateBuffers(Camera *camera, Stream *stream) = 0;
virtual int freeBuffers(Camera *camera, Stream *stream) = 0; virtual int freeBuffers(Camera *camera, Stream *stream) = 0;

View file

@ -139,11 +139,11 @@ public:
PipelineHandlerIPU3(CameraManager *manager); PipelineHandlerIPU3(CameraManager *manager);
~PipelineHandlerIPU3(); ~PipelineHandlerIPU3();
std::map<Stream *, StreamConfiguration> CameraConfiguration
streamConfiguration(Camera *camera, streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) override; const std::vector<StreamUsage> &usages) override;
int configureStreams(Camera *camera, int configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) override; const CameraConfiguration &config) override;
int allocateBuffers(Camera *camera, Stream *stream) override; int allocateBuffers(Camera *camera, Stream *stream) override;
int freeBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override;
@ -204,11 +204,11 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3()
imguMediaDev_->release(); imguMediaDev_->release();
} }
std::map<Stream *, StreamConfiguration> CameraConfiguration
PipelineHandlerIPU3::streamConfiguration(Camera *camera, PipelineHandlerIPU3::streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) const std::vector<StreamUsage> &usages)
{ {
std::map<Stream *, StreamConfiguration> configs; CameraConfiguration configs;
IPU3CameraData *data = cameraData(camera); IPU3CameraData *data = cameraData(camera);
StreamConfiguration *config = &configs[&data->stream_]; StreamConfiguration *config = &configs[&data->stream_];
@ -234,7 +234,7 @@ PipelineHandlerIPU3::streamConfiguration(Camera *camera,
} }
int PipelineHandlerIPU3::configureStreams(Camera *camera, int PipelineHandlerIPU3::configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) const CameraConfiguration &config)
{ {
IPU3CameraData *data = cameraData(camera); IPU3CameraData *data = cameraData(camera);
const StreamConfiguration &cfg = config[&data->stream_]; const StreamConfiguration &cfg = config[&data->stream_];

View file

@ -26,11 +26,11 @@ public:
PipelineHandlerUVC(CameraManager *manager); PipelineHandlerUVC(CameraManager *manager);
~PipelineHandlerUVC(); ~PipelineHandlerUVC();
std::map<Stream *, StreamConfiguration> CameraConfiguration
streamConfiguration(Camera *camera, streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) override; const std::vector<StreamUsage> &usages) override;
int configureStreams(Camera *camera, int configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) override; const CameraConfiguration &config) override;
int allocateBuffers(Camera *camera, Stream *stream) override; int allocateBuffers(Camera *camera, Stream *stream) override;
int freeBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override;
@ -82,12 +82,12 @@ PipelineHandlerUVC::~PipelineHandlerUVC()
media_->release(); media_->release();
} }
std::map<Stream *, StreamConfiguration> CameraConfiguration
PipelineHandlerUVC::streamConfiguration(Camera *camera, PipelineHandlerUVC::streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) const std::vector<StreamUsage> &usages)
{ {
UVCCameraData *data = cameraData(camera); UVCCameraData *data = cameraData(camera);
std::map<Stream *, StreamConfiguration> configs; CameraConfiguration configs;
StreamConfiguration config{}; StreamConfiguration config{};
config.width = 640; config.width = 640;
@ -101,10 +101,10 @@ PipelineHandlerUVC::streamConfiguration(Camera *camera,
} }
int PipelineHandlerUVC::configureStreams(Camera *camera, int PipelineHandlerUVC::configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) const CameraConfiguration &config)
{ {
UVCCameraData *data = cameraData(camera); UVCCameraData *data = cameraData(camera);
StreamConfiguration *cfg = &config[&data->stream_]; const StreamConfiguration *cfg = &config[&data->stream_];
int ret; int ret;
LOG(UVC, Debug) << "Configure the camera for resolution " LOG(UVC, Debug) << "Configure the camera for resolution "

View file

@ -26,11 +26,11 @@ public:
PipelineHandlerVimc(CameraManager *manager); PipelineHandlerVimc(CameraManager *manager);
~PipelineHandlerVimc(); ~PipelineHandlerVimc();
std::map<Stream *, StreamConfiguration> CameraConfiguration
streamConfiguration(Camera *camera, streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) override; const std::vector<StreamUsage> &usages) override;
int configureStreams(Camera *camera, int configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) override; const CameraConfiguration &config) override;
int allocateBuffers(Camera *camera, Stream *stream) override; int allocateBuffers(Camera *camera, Stream *stream) override;
int freeBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override;
@ -82,12 +82,12 @@ PipelineHandlerVimc::~PipelineHandlerVimc()
media_->release(); media_->release();
} }
std::map<Stream *, StreamConfiguration> CameraConfiguration
PipelineHandlerVimc::streamConfiguration(Camera *camera, PipelineHandlerVimc::streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) const std::vector<StreamUsage> &usages)
{ {
VimcCameraData *data = cameraData(camera); VimcCameraData *data = cameraData(camera);
std::map<Stream *, StreamConfiguration> configs; CameraConfiguration configs;
StreamConfiguration config{}; StreamConfiguration config{};
config.width = 640; config.width = 640;
@ -101,10 +101,10 @@ PipelineHandlerVimc::streamConfiguration(Camera *camera,
} }
int PipelineHandlerVimc::configureStreams(Camera *camera, int PipelineHandlerVimc::configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config) const CameraConfiguration &config)
{ {
VimcCameraData *data = cameraData(camera); VimcCameraData *data = cameraData(camera);
StreamConfiguration *cfg = &config[&data->stream_]; const StreamConfiguration *cfg = &config[&data->stream_];
int ret; int ret;
LOG(VIMC, Debug) << "Configure the camera for resolution " LOG(VIMC, Debug) << "Configure the camera for resolution "

View file

@ -163,15 +163,15 @@ PipelineHandler::~PipelineHandler()
* The intended companion to this is \a configureStreams() which can be used to * The intended companion to this is \a configureStreams() which can be used to
* change the group of streams parameters. * change the group of streams parameters.
* *
* \return A map of successfully retrieved streams and configurations or an * \return A valid CameraConfiguration if the requested usages can be satisfied,
* empty map on error. * or a invalid configuration otherwise
*/ */
/** /**
* \fn PipelineHandler::configureStreams() * \fn PipelineHandler::configureStreams()
* \brief Configure a group of streams for capture * \brief Configure a group of streams for capture
* \param[in] camera The camera to configure * \param[in] camera The camera to configure
* \param[in] config A map of stream configurations to apply * \param[in] config The camera configurations to setup
* *
* Configure the specified group of streams for \a camera according to the * Configure the specified group of streams for \a camera according to the
* configuration specified in \a configs. The intended caller of this interface * configuration specified in \a configs. The intended caller of this interface

View file

@ -98,7 +98,7 @@ int MainWindow::startCapture()
int ret; int ret;
config_ = camera_->streamConfiguration({ Stream::VideoRecording() }); config_ = camera_->streamConfiguration({ Stream::VideoRecording() });
Stream *stream = config_.begin()->first; Stream *stream = config_.front();
ret = camera_->configureStreams(config_); ret = camera_->configureStreams(config_);
if (ret < 0) { if (ret < 0) {
std::cout << "Failed to configure camera" << std::endl; std::cout << "Failed to configure camera" << std::endl;

View file

@ -46,7 +46,7 @@ private:
std::shared_ptr<Camera> camera_; std::shared_ptr<Camera> camera_;
bool isCapturing_; bool isCapturing_;
std::map<Stream *, StreamConfiguration> config_; CameraConfiguration config_;
ViewFinder *viewfinder_; ViewFinder *viewfinder_;
}; };

View file

@ -45,21 +45,3 @@ void CameraTest::cleanup()
cm_->stop(); cm_->stop();
}; };
bool CameraTest::configurationValid(const std::map<Stream *, StreamConfiguration> &config) const
{
/* Test that the configuration is not empty. */
if (config.empty())
return false;
/* Test that configuration is valid. */
for (auto const &it : config) {
const StreamConfiguration &conf = it.second;
if (conf.width == 0 || conf.height == 0 ||
conf.pixelFormat == 0 || conf.bufferCount == 0)
return false;
}
return true;
}

View file

@ -23,8 +23,6 @@ protected:
int init(); int init();
void cleanup(); void cleanup();
bool configurationValid(const std::map<Stream *, StreamConfiguration> &config) const;
std::shared_ptr<Camera> camera_; std::shared_ptr<Camera> camera_;
private: private:

View file

@ -42,12 +42,12 @@ protected:
int run() int run()
{ {
std::map<Stream *, StreamConfiguration> conf = CameraConfiguration conf =
camera_->streamConfiguration({ Stream::VideoRecording() }); camera_->streamConfiguration({ Stream::VideoRecording() });
Stream *stream = conf.begin()->first; Stream *stream = conf.front();
StreamConfiguration *sconf = &conf.begin()->second; StreamConfiguration *sconf = &conf[stream];
if (!configurationValid(conf)) { if (!conf.isValid()) {
cout << "Failed to read default configuration" << endl; cout << "Failed to read default configuration" << endl;
return TestFail; return TestFail;
} }

View file

@ -18,17 +18,11 @@ class ConfigurationDefault : public CameraTest
protected: protected:
int run() int run()
{ {
std::map<Stream *, StreamConfiguration> conf; CameraConfiguration conf;
/* Test asking for configuration for a video stream. */ /* Test asking for configuration for a video stream. */
conf = camera_->streamConfiguration({ Stream::VideoRecording() }); conf = camera_->streamConfiguration({ Stream::VideoRecording() });
if (conf.empty()) { if (!conf.isValid()) {
cout << "Failed to retrieve configuration for video streams"
<< endl;
return TestFail;
}
if (!configurationValid(conf)) {
cout << "Default configuration invalid" << endl; cout << "Default configuration invalid" << endl;
return TestFail; return TestFail;
} }
@ -38,7 +32,7 @@ protected:
* stream usages returns an empty list of configurations. * stream usages returns an empty list of configurations.
*/ */
conf = camera_->streamConfiguration({}); conf = camera_->streamConfiguration({});
if (!conf.empty()) { if (conf.isValid()) {
cout << "Failed to retrieve configuration for empty usage list" cout << "Failed to retrieve configuration for empty usage list"
<< endl; << endl;
return TestFail; return TestFail;

View file

@ -18,11 +18,11 @@ class ConfigurationSet : public CameraTest
protected: protected:
int run() int run()
{ {
std::map<Stream *, StreamConfiguration> conf = CameraConfiguration conf =
camera_->streamConfiguration({ Stream::VideoRecording() }); camera_->streamConfiguration({ Stream::VideoRecording() });
StreamConfiguration *sconf = &conf.begin()->second; StreamConfiguration *sconf = &conf[conf.front()];
if (!configurationValid(conf)) { if (!conf.isValid()) {
cout << "Failed to read default configuration" << endl; cout << "Failed to read default configuration" << endl;
return TestFail; return TestFail;
} }

View file

@ -265,7 +265,7 @@ protected:
return TestPass; return TestPass;
} }
std::map<Stream *, StreamConfiguration> defconf_; CameraConfiguration defconf_;
}; };
} /* namespace */ } /* namespace */