libcamera/test/camera/statemachine.cpp
Niklas Söderlund 20a6455e0b libcamera: camera: Add support for stream usages
Instead of requesting the default configuration for a set of streams
where the application has to figure out which streams provided by the
camera is best suited for its intended usage, have the library figure
this out by using stream usages.

The application asks the library for a list of streams and a suggested
default configuration for them by supplying a list of stream usages.
Once the list is retrieved the application can fine-tune the returned
configuration and then try to apply it to the camera.

Currently no pipeline handler is prepared to handle stream usages but
nor did it make use of the list of Stream IDs which was the previous
interface. The main reason for this is that all cameras currently only
provide one stream each. This will still be the case but the API will be
prepared to expand both pipeline handlers and applications to support
streams usages.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-05 22:07:47 +02:00

273 lines
5.5 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* libcamera Camera API tests
*/
#include <iostream>
#include "camera_test.h"
using namespace std;
namespace {
class Statemachine : public CameraTest
{
protected:
int testAvailable()
{
/* Test operations which should fail. */
if (camera_->configureStreams(defconf_) != -EACCES)
return TestFail;
if (camera_->allocateBuffers() != -EACCES)
return TestFail;
if (camera_->freeBuffers() != -EACCES)
return TestFail;
if (camera_->createRequest())
return TestFail;
if (camera_->start() != -EACCES)
return TestFail;
Request request(camera_.get());
if (camera_->queueRequest(&request) != -EACCES)
return TestFail;
if (camera_->stop() != -EACCES)
return TestFail;
/* Test operations which should pass. */
if (camera_->release())
return TestFail;
/* Test valid state transitions, end in Acquired state. */
if (camera_->acquire())
return TestFail;
return TestPass;
}
int testAcquired()
{
/* Test operations which should fail. */
if (camera_->acquire() != -EBUSY)
return TestFail;
if (camera_->allocateBuffers() != -EACCES)
return TestFail;
if (camera_->freeBuffers() != -EACCES)
return TestFail;
if (camera_->createRequest())
return TestFail;
if (camera_->start() != -EACCES)
return TestFail;
Request request(camera_.get());
if (camera_->queueRequest(&request) != -EACCES)
return TestFail;
if (camera_->stop() != -EACCES)
return TestFail;
/* Test valid state transitions, end in Configured state. */
if (camera_->release())
return TestFail;
if (camera_->acquire())
return TestFail;
if (camera_->configureStreams(defconf_))
return TestFail;
return TestPass;
}
int testConfigured()
{
/* Test operations which should fail. */
if (camera_->acquire() != -EBUSY)
return TestFail;
if (camera_->freeBuffers() != -EACCES)
return TestFail;
if (camera_->createRequest())
return TestFail;
Request request(camera_.get());
if (camera_->queueRequest(&request) != -EACCES)
return TestFail;
if (camera_->start() != -EACCES)
return TestFail;
if (camera_->stop() != -EACCES)
return TestFail;
/* Test operations which should pass. */
if (camera_->configureStreams(defconf_))
return TestFail;
/* Test valid state transitions, end in Prepared state. */
if (camera_->release())
return TestFail;
if (camera_->acquire())
return TestFail;
if (camera_->configureStreams(defconf_))
return TestFail;
if (camera_->allocateBuffers())
return TestFail;
return TestPass;
}
int testPrepared()
{
/* Test operations which should fail. */
if (camera_->acquire() != -EBUSY)
return TestFail;
if (camera_->release() != -EBUSY)
return TestFail;
if (camera_->configureStreams(defconf_) != -EACCES)
return TestFail;
if (camera_->allocateBuffers() != -EACCES)
return TestFail;
Request request1(camera_.get());
if (camera_->queueRequest(&request1) != -EACCES)
return TestFail;
if (camera_->stop() != -EACCES)
return TestFail;
/* Test operations which should pass. */
Request *request2 = camera_->createRequest();
if (!request2)
return TestFail;
/* Never handed to hardware so need to manually delete it. */
delete request2;
/* Test valid state transitions, end in Running state. */
if (camera_->freeBuffers())
return TestFail;
if (camera_->release())
return TestFail;
if (camera_->acquire())
return TestFail;
if (camera_->configureStreams(defconf_))
return TestFail;
if (camera_->allocateBuffers())
return TestFail;
if (camera_->start())
return TestFail;
return TestPass;
}
int testRuning()
{
/* Test operations which should fail. */
if (camera_->acquire() != -EBUSY)
return TestFail;
if (camera_->release() != -EBUSY)
return TestFail;
if (camera_->configureStreams(defconf_) != -EACCES)
return TestFail;
if (camera_->allocateBuffers() != -EACCES)
return TestFail;
if (camera_->freeBuffers() != -EACCES)
return TestFail;
if (camera_->start() != -EACCES)
return TestFail;
/* Test operations which should pass. */
Request *request = camera_->createRequest();
if (!request)
return TestFail;
Stream *stream = *camera_->streams().begin();
BufferPool &pool = stream->bufferPool();
Buffer &buffer = pool.buffers().front();
std::map<Stream *, Buffer *> map = { { stream, &buffer } };
if (request->setBuffers(map))
return TestFail;
if (camera_->queueRequest(request))
return TestFail;
/* Test valid state transitions, end in Available state. */
if (camera_->stop())
return TestFail;
if (camera_->freeBuffers())
return TestFail;
if (camera_->release())
return TestFail;
return TestPass;
}
int run()
{
defconf_ = camera_->streamConfiguration({ Stream::VideoRecording() });
if (testAvailable() != TestPass) {
cout << "State machine in Available state failed" << endl;
return TestFail;
}
if (testAcquired() != TestPass) {
cout << "State machine in Acquired state failed" << endl;
return TestFail;
}
if (testConfigured() != TestPass) {
cout << "State machine in Configured state failed" << endl;
return TestFail;
}
if (testPrepared() != TestPass) {
cout << "State machine in Prepared state failed" << endl;
return TestFail;
}
if (testRuning() != TestPass) {
cout << "State machine in Running state failed" << endl;
return TestFail;
}
return TestPass;
}
std::map<Stream *, StreamConfiguration> defconf_;
};
} /* namespace */
TEST_REGISTER(Statemachine);