libcamera: pipeline: rkisp1: Remove Timeline
There are no users left of the Timeline and there is no longer a need to keep emulating a start of exposure event as the CSI-2 resciver reports it. Remove the Timeline helper and what's left of it's integration in the pipeline. There is no functional change as nothing i the pipeline uses the Timeline. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
ea8b576a8c
commit
2b57d712a2
4 changed files with 0 additions and 344 deletions
|
@ -3,5 +3,4 @@
|
|||
libcamera_sources += files([
|
||||
'rkisp1.cpp',
|
||||
'rkisp1_path.cpp',
|
||||
'timeline.cpp',
|
||||
])
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "libcamera/internal/v4l2_videodevice.h"
|
||||
|
||||
#include "rkisp1_path.h"
|
||||
#include "timeline.h"
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
|
@ -43,12 +42,6 @@ LOG_DEFINE_CATEGORY(RkISP1)
|
|||
class PipelineHandlerRkISP1;
|
||||
class RkISP1CameraData;
|
||||
|
||||
enum RkISP1ActionType {
|
||||
SetSensor,
|
||||
SOE,
|
||||
QueueBuffers,
|
||||
};
|
||||
|
||||
struct RkISP1FrameInfo {
|
||||
unsigned int frame;
|
||||
Request *request;
|
||||
|
@ -81,41 +74,6 @@ private:
|
|||
std::map<unsigned int, RkISP1FrameInfo *> frameInfo_;
|
||||
};
|
||||
|
||||
class RkISP1Timeline : public Timeline
|
||||
{
|
||||
public:
|
||||
RkISP1Timeline()
|
||||
: Timeline()
|
||||
{
|
||||
setDelay(SetSensor, -1, 5);
|
||||
setDelay(SOE, 0, -1);
|
||||
setDelay(QueueBuffers, -1, 10);
|
||||
}
|
||||
|
||||
void bufferReady(FrameBuffer *buffer)
|
||||
{
|
||||
/*
|
||||
* Calculate SOE by taking the end of DMA set by the kernel and applying
|
||||
* the time offsets provideprovided by the IPA to find the best estimate
|
||||
* of SOE.
|
||||
*/
|
||||
|
||||
ASSERT(frameOffset(SOE) == 0);
|
||||
|
||||
utils::time_point soe = std::chrono::time_point<utils::clock>()
|
||||
+ std::chrono::nanoseconds(buffer->metadata().timestamp)
|
||||
+ timeOffset(SOE);
|
||||
|
||||
notifyStartOfExposure(buffer->metadata().sequence, soe);
|
||||
}
|
||||
|
||||
void setDelay(unsigned int type, int frame, int msdelay)
|
||||
{
|
||||
utils::duration delay = std::chrono::milliseconds(msdelay);
|
||||
setRawDelay(type, frame, delay);
|
||||
}
|
||||
};
|
||||
|
||||
class RkISP1CameraData : public CameraData
|
||||
{
|
||||
public:
|
||||
|
@ -135,7 +93,6 @@ public:
|
|||
unsigned int frame_;
|
||||
std::vector<IPABuffer> ipaBuffers_;
|
||||
RkISP1Frames frameInfo_;
|
||||
RkISP1Timeline timeline_;
|
||||
|
||||
RkISP1MainPath *mainPath_;
|
||||
RkISP1SelfPath *selfPath_;
|
||||
|
@ -874,8 +831,6 @@ void PipelineHandlerRkISP1::stop(Camera *camera)
|
|||
|
||||
data->ipa_->stop();
|
||||
|
||||
data->timeline_.reset();
|
||||
|
||||
data->frameInfo_.clear();
|
||||
|
||||
freeBuffers(camera);
|
||||
|
|
|
@ -1,227 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2019, Google Inc.
|
||||
*
|
||||
* timeline.cpp - Timeline for per-frame control
|
||||
*/
|
||||
|
||||
#include "timeline.h"
|
||||
|
||||
#include "libcamera/internal/log.h"
|
||||
|
||||
/**
|
||||
* \file timeline.h
|
||||
* \brief Timeline for per-frame control
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
LOG_DEFINE_CATEGORY(Timeline)
|
||||
|
||||
/**
|
||||
* \class FrameAction
|
||||
* \brief Action that can be schedule on a Timeline
|
||||
*
|
||||
* A frame action is an event schedule to be executed on a Timeline. A frame
|
||||
* action has two primal attributes a frame number and a type.
|
||||
*
|
||||
* The frame number describes the frame to which the action is associated. The
|
||||
* type is a numerical ID which identifies the action within the pipeline and
|
||||
* IPA protocol.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class Timeline
|
||||
* \brief Executor of FrameAction
|
||||
*
|
||||
* The timeline has three primary functions:
|
||||
*
|
||||
* 1. Keep track of the Start of Exposure (SOE) for every frame processed by
|
||||
* the hardware. Using this information it shall keep an up-to-date estimate
|
||||
* of the frame interval (time between two consecutive SOE events).
|
||||
*
|
||||
* The estimated frame interval together with recorded SOE events are the
|
||||
* foundation for how the timeline schedule FrameAction at specific points
|
||||
* in time.
|
||||
* \todo Improve the frame interval estimation algorithm.
|
||||
*
|
||||
* 2. Keep track of current delays for different types of actions. The delays
|
||||
* for different actions might differ during a capture session. Exposure time
|
||||
* effects the over all FPS and different ISP parameters might impacts its
|
||||
* processing time.
|
||||
*
|
||||
* The action type delays shall be updated by the IPA in conjunction with
|
||||
* how it changes the capture parameters.
|
||||
*
|
||||
* 3. Schedule actions on the timeline. This is the process of taking a
|
||||
* FrameAction which contains an abstract description of what frame and
|
||||
* what type of action it contains and turning that into an time point
|
||||
* and make sure the action is executed at that time.
|
||||
*/
|
||||
|
||||
Timeline::Timeline()
|
||||
: frameInterval_(0)
|
||||
{
|
||||
timer_.timeout.connect(this, &Timeline::timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reset and stop the timeline
|
||||
*
|
||||
* The timeline needs to be reset when the timeline should no longer execute
|
||||
* actions. A timeline should be reset between two capture sessions to prevent
|
||||
* the old capture session to effect the second one.
|
||||
*/
|
||||
void Timeline::reset()
|
||||
{
|
||||
timer_.stop();
|
||||
|
||||
actions_.clear();
|
||||
history_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Schedule an action on the timeline
|
||||
* \param[in] action FrameAction to schedule
|
||||
*
|
||||
* The act of scheduling an action to the timeline is the process of taking
|
||||
* the properties of the action (type, frame and time offsets) and translating
|
||||
* that to a time point using the current values for the action type timings
|
||||
* value recorded in the timeline. If an action is scheduled too late, execute
|
||||
* it immediately.
|
||||
*/
|
||||
void Timeline::scheduleAction(std::unique_ptr<FrameAction> action)
|
||||
{
|
||||
unsigned int lastFrame;
|
||||
utils::time_point lastTime;
|
||||
|
||||
if (history_.empty()) {
|
||||
lastFrame = 0;
|
||||
lastTime = std::chrono::steady_clock::now();
|
||||
} else {
|
||||
lastFrame = history_.back().first;
|
||||
lastTime = history_.back().second;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate when the action shall be schedule by first finding out how
|
||||
* many frames in the future the action acts on and then add the actions
|
||||
* frame offset. After the spatial frame offset is found out translate
|
||||
* that to a time point by using the last estimated start of exposure
|
||||
* (SOE) as the fixed offset. Lastly add the action time offset to the
|
||||
* time point.
|
||||
*/
|
||||
int frame = action->frame() - lastFrame + frameOffset(action->type());
|
||||
utils::time_point deadline = lastTime + frame * frameInterval_
|
||||
+ timeOffset(action->type());
|
||||
|
||||
utils::time_point now = std::chrono::steady_clock::now();
|
||||
if (deadline < now) {
|
||||
LOG(Timeline, Warning)
|
||||
<< "Action scheduled too late "
|
||||
<< utils::time_point_to_string(deadline)
|
||||
<< ", run now " << utils::time_point_to_string(now);
|
||||
action->run();
|
||||
} else {
|
||||
actions_.emplace(deadline, std::move(action));
|
||||
updateDeadline();
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::notifyStartOfExposure(unsigned int frame, utils::time_point time)
|
||||
{
|
||||
history_.push_back(std::make_pair(frame, time));
|
||||
|
||||
if (history_.size() <= HISTORY_DEPTH / 2)
|
||||
return;
|
||||
|
||||
while (history_.size() > HISTORY_DEPTH)
|
||||
history_.pop_front();
|
||||
|
||||
/* Update esitmated time between two start of exposures. */
|
||||
utils::duration sumExposures(0);
|
||||
unsigned int numExposures = 0;
|
||||
|
||||
utils::time_point lastTime;
|
||||
for (auto it = history_.begin(); it != history_.end(); it++) {
|
||||
if (it != history_.begin()) {
|
||||
sumExposures += it->second - lastTime;
|
||||
numExposures++;
|
||||
}
|
||||
|
||||
lastTime = it->second;
|
||||
}
|
||||
|
||||
frameInterval_ = sumExposures;
|
||||
if (numExposures)
|
||||
frameInterval_ /= numExposures;
|
||||
}
|
||||
|
||||
int Timeline::frameOffset(unsigned int type) const
|
||||
{
|
||||
const auto it = delays_.find(type);
|
||||
if (it == delays_.end()) {
|
||||
LOG(Timeline, Error)
|
||||
<< "No frame offset set for action type " << type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return it->second.first;
|
||||
}
|
||||
|
||||
utils::duration Timeline::timeOffset(unsigned int type) const
|
||||
{
|
||||
const auto it = delays_.find(type);
|
||||
if (it == delays_.end()) {
|
||||
LOG(Timeline, Error)
|
||||
<< "No time offset set for action type " << type;
|
||||
return utils::duration::zero();
|
||||
}
|
||||
|
||||
return it->second.second;
|
||||
}
|
||||
|
||||
void Timeline::setRawDelay(unsigned int type, int frame, utils::duration time)
|
||||
{
|
||||
delays_[type] = std::make_pair(frame, time);
|
||||
}
|
||||
|
||||
void Timeline::updateDeadline()
|
||||
{
|
||||
if (actions_.empty())
|
||||
return;
|
||||
|
||||
const utils::time_point &deadline = actions_.begin()->first;
|
||||
|
||||
if (timer_.isRunning() && deadline >= timer_.deadline())
|
||||
return;
|
||||
|
||||
if (deadline <= std::chrono::steady_clock::now()) {
|
||||
timeout(&timer_);
|
||||
return;
|
||||
}
|
||||
|
||||
timer_.start(deadline);
|
||||
}
|
||||
|
||||
void Timeline::timeout([[maybe_unused]] Timer *timer)
|
||||
{
|
||||
utils::time_point now = std::chrono::steady_clock::now();
|
||||
|
||||
for (auto it = actions_.begin(); it != actions_.end();) {
|
||||
const utils::time_point &sched = it->first;
|
||||
|
||||
if (sched > now)
|
||||
break;
|
||||
|
||||
FrameAction *action = it->second.get();
|
||||
|
||||
action->run();
|
||||
|
||||
it = actions_.erase(it);
|
||||
}
|
||||
|
||||
updateDeadline();
|
||||
}
|
||||
|
||||
} /* namespace libcamera */
|
|
@ -1,71 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2019, Google Inc.
|
||||
*
|
||||
* timeline.h - Timeline for per-frame controls
|
||||
*/
|
||||
#ifndef __LIBCAMERA_TIMELINE_H__
|
||||
#define __LIBCAMERA_TIMELINE_H__
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "libcamera/internal/timer.h"
|
||||
#include "libcamera/internal/utils.h"
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
class FrameAction
|
||||
{
|
||||
public:
|
||||
FrameAction(unsigned int frame, unsigned int type)
|
||||
: frame_(frame), type_(type) {}
|
||||
|
||||
virtual ~FrameAction() = default;
|
||||
|
||||
unsigned int frame() const { return frame_; }
|
||||
unsigned int type() const { return type_; }
|
||||
|
||||
virtual void run() = 0;
|
||||
|
||||
private:
|
||||
unsigned int frame_;
|
||||
unsigned int type_;
|
||||
};
|
||||
|
||||
class Timeline
|
||||
{
|
||||
public:
|
||||
Timeline();
|
||||
virtual ~Timeline() = default;
|
||||
|
||||
virtual void reset();
|
||||
virtual void scheduleAction(std::unique_ptr<FrameAction> action);
|
||||
virtual void notifyStartOfExposure(unsigned int frame, utils::time_point time);
|
||||
|
||||
utils::duration frameInterval() const { return frameInterval_; }
|
||||
|
||||
protected:
|
||||
int frameOffset(unsigned int type) const;
|
||||
utils::duration timeOffset(unsigned int type) const;
|
||||
|
||||
void setRawDelay(unsigned int type, int frame, utils::duration time);
|
||||
|
||||
std::map<unsigned int, std::pair<int, utils::duration>> delays_;
|
||||
|
||||
private:
|
||||
static constexpr unsigned int HISTORY_DEPTH = 10;
|
||||
|
||||
void timeout(Timer *timer);
|
||||
void updateDeadline();
|
||||
|
||||
std::list<std::pair<unsigned int, utils::time_point>> history_;
|
||||
std::multimap<utils::time_point, std::unique_ptr<FrameAction>> actions_;
|
||||
utils::duration frameInterval_;
|
||||
|
||||
Timer timer_;
|
||||
};
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
||||
#endif /* __LIBCAMERA_TIMELINE_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue