[{"id":13945,"web_url":"https://patchwork.libcamera.org/comment/13945/","msgid":"<20201127110614.sgky3464jflvtkhm@uno.localdomain>","date":"2020-11-27T11:06:14","subject":"Re: [libcamera-devel] [PATCH v3 8/8] libcamera: pipeline: rkisp1:\n\tRemove Timeline","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Mon, Nov 23, 2020 at 11:12:34PM +0100, Niklas Söderlund wrote:\n> There are no users left of the Timeline and there is no longer a need to\n> keep emulating a start of exposure event as the CSI-2 resciver reports\n> it. Remove the Timeline helper and what's left of it's integration in\n> the pipeline.\n>\n> There is no functional change as nothing i the pipeline uses the\n> Timeline.\n>\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  src/libcamera/pipeline/rkisp1/meson.build  |   1 -\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp   |  45 ----\n>  src/libcamera/pipeline/rkisp1/timeline.cpp | 227 ---------------------\n>  src/libcamera/pipeline/rkisp1/timeline.h   |  71 -------\n\nNice!\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n>  4 files changed, 344 deletions(-)\n>  delete mode 100644 src/libcamera/pipeline/rkisp1/timeline.cpp\n>  delete mode 100644 src/libcamera/pipeline/rkisp1/timeline.h\n>\n> diff --git a/src/libcamera/pipeline/rkisp1/meson.build b/src/libcamera/pipeline/rkisp1/meson.build\n> index 5cd40d949d543fa9..cad66535c25f8cc0 100644\n> --- a/src/libcamera/pipeline/rkisp1/meson.build\n> +++ b/src/libcamera/pipeline/rkisp1/meson.build\n> @@ -3,5 +3,4 @@\n>  libcamera_sources += files([\n>      'rkisp1.cpp',\n>      'rkisp1_path.cpp',\n> -    'timeline.cpp',\n>  ])\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 3662a53ac4a43fcd..c2b61e88ec34aa60 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -33,7 +33,6 @@\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>\n>  #include \"rkisp1_path.h\"\n> -#include \"timeline.h\"\n>\n>  namespace libcamera {\n>\n> @@ -42,12 +41,6 @@ LOG_DEFINE_CATEGORY(RkISP1)\n>  class PipelineHandlerRkISP1;\n>  class RkISP1CameraData;\n>\n> -enum RkISP1ActionType {\n> -\tSetSensor,\n> -\tSOE,\n> -\tQueueBuffers,\n> -};\n> -\n>  struct RkISP1FrameInfo {\n>  \tunsigned int frame;\n>  \tRequest *request;\n> @@ -80,41 +73,6 @@ private:\n>  \tstd::map<unsigned int, RkISP1FrameInfo *> frameInfo_;\n>  };\n>\n> -class RkISP1Timeline : public Timeline\n> -{\n> -public:\n> -\tRkISP1Timeline()\n> -\t\t: Timeline()\n> -\t{\n> -\t\tsetDelay(SetSensor, -1, 5);\n> -\t\tsetDelay(SOE, 0, -1);\n> -\t\tsetDelay(QueueBuffers, -1, 10);\n> -\t}\n> -\n> -\tvoid bufferReady(FrameBuffer *buffer)\n> -\t{\n> -\t\t/*\n> -\t\t * Calculate SOE by taking the end of DMA set by the kernel and applying\n> -\t\t * the time offsets provideprovided by the IPA to find the best estimate\n> -\t\t * of SOE.\n> -\t\t */\n> -\n> -\t\tASSERT(frameOffset(SOE) == 0);\n> -\n> -\t\tutils::time_point soe = std::chrono::time_point<utils::clock>()\n> -\t\t\t+ std::chrono::nanoseconds(buffer->metadata().timestamp)\n> -\t\t\t+ timeOffset(SOE);\n> -\n> -\t\tnotifyStartOfExposure(buffer->metadata().sequence, soe);\n> -\t}\n> -\n> -\tvoid setDelay(unsigned int type, int frame, int msdelay)\n> -\t{\n> -\t\tutils::duration delay = std::chrono::milliseconds(msdelay);\n> -\t\tsetRawDelay(type, frame, delay);\n> -\t}\n> -};\n> -\n>  class RkISP1CameraData : public CameraData\n>  {\n>  public:\n> @@ -140,7 +98,6 @@ public:\n>  \tunsigned int frame_;\n>  \tstd::vector<IPABuffer> ipaBuffers_;\n>  \tRkISP1Frames frameInfo_;\n> -\tRkISP1Timeline timeline_;\n>\n>  \tRkISP1MainPath *mainPath_;\n>  \tRkISP1SelfPath *selfPath_;\n> @@ -887,8 +844,6 @@ void PipelineHandlerRkISP1::stop(Camera *camera)\n>\n>  \tdata->ipa_->stop();\n>\n> -\tdata->timeline_.reset();\n> -\n>  \tdata->frameInfo_.clear();\n>\n>  \tfreeBuffers(camera);\n> diff --git a/src/libcamera/pipeline/rkisp1/timeline.cpp b/src/libcamera/pipeline/rkisp1/timeline.cpp\n> deleted file mode 100644\n> index 6b83bbe5b5892531..0000000000000000\n> --- a/src/libcamera/pipeline/rkisp1/timeline.cpp\n> +++ /dev/null\n> @@ -1,227 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * timeline.cpp - Timeline for per-frame control\n> - */\n> -\n> -#include \"timeline.h\"\n> -\n> -#include \"libcamera/internal/log.h\"\n> -\n> -/**\n> - * \\file timeline.h\n> - * \\brief Timeline for per-frame control\n> - */\n> -\n> -namespace libcamera {\n> -\n> -LOG_DEFINE_CATEGORY(Timeline)\n> -\n> -/**\n> - * \\class FrameAction\n> - * \\brief Action that can be schedule on a Timeline\n> - *\n> - * A frame action is an event schedule to be executed on a Timeline. A frame\n> - * action has two primal attributes a frame number and a type.\n> - *\n> - * The frame number describes the frame to which the action is associated. The\n> - * type is a numerical ID which identifies the action within the pipeline and\n> - * IPA protocol.\n> - */\n> -\n> -/**\n> - * \\class Timeline\n> - * \\brief Executor of FrameAction\n> - *\n> - * The timeline has three primary functions:\n> - *\n> - * 1. Keep track of the Start of Exposure (SOE) for every frame processed by\n> - *    the hardware. Using this information it shall keep an up-to-date estimate\n> - *    of the frame interval (time between two consecutive SOE events).\n> - *\n> - *    The estimated frame interval together with recorded SOE events are the\n> - *    foundation for how the timeline schedule FrameAction at specific points\n> - *    in time.\n> - *    \\todo Improve the frame interval estimation algorithm.\n> - *\n> - * 2. Keep track of current delays for different types of actions. The delays\n> - *    for different actions might differ during a capture session. Exposure time\n> - *    effects the over all FPS and different ISP parameters might impacts its\n> - *    processing time.\n> - *\n> - *    The action type delays shall be updated by the IPA in conjunction with\n> - *    how it changes the capture parameters.\n> - *\n> - * 3. Schedule actions on the timeline. This is the process of taking a\n> - *    FrameAction which contains an abstract description of what frame and\n> - *    what type of action it contains and turning that into an time point\n> - *    and make sure the action is executed at that time.\n> - */\n> -\n> -Timeline::Timeline()\n> -\t: frameInterval_(0)\n> -{\n> -\ttimer_.timeout.connect(this, &Timeline::timeout);\n> -}\n> -\n> -/**\n> - * \\brief Reset and stop the timeline\n> - *\n> - * The timeline needs to be reset when the timeline should no longer execute\n> - * actions. A timeline should be reset between two capture sessions to prevent\n> - * the old capture session to effect the second one.\n> - */\n> -void Timeline::reset()\n> -{\n> -\ttimer_.stop();\n> -\n> -\tactions_.clear();\n> -\thistory_.clear();\n> -}\n> -\n> -/**\n> - * \\brief Schedule an action on the timeline\n> - * \\param[in] action FrameAction to schedule\n> - *\n> - * The act of scheduling an action to the timeline is the process of taking\n> - * the properties of the action (type, frame and time offsets) and translating\n> - * that to a time point using the current values for the action type timings\n> - * value recorded in the timeline. If an action is scheduled too late, execute\n> - * it immediately.\n> - */\n> -void Timeline::scheduleAction(std::unique_ptr<FrameAction> action)\n> -{\n> -\tunsigned int lastFrame;\n> -\tutils::time_point lastTime;\n> -\n> -\tif (history_.empty()) {\n> -\t\tlastFrame = 0;\n> -\t\tlastTime = std::chrono::steady_clock::now();\n> -\t} else {\n> -\t\tlastFrame = history_.back().first;\n> -\t\tlastTime = history_.back().second;\n> -\t}\n> -\n> -\t/*\n> -\t * Calculate when the action shall be schedule by first finding out how\n> -\t * many frames in the future the action acts on and then add the actions\n> -\t * frame offset. After the spatial frame offset is found out translate\n> -\t * that to a time point by using the last estimated start of exposure\n> -\t * (SOE) as the fixed offset. Lastly add the action time offset to the\n> -\t * time point.\n> -\t */\n> -\tint frame = action->frame() - lastFrame + frameOffset(action->type());\n> -\tutils::time_point deadline = lastTime + frame * frameInterval_\n> -\t\t+ timeOffset(action->type());\n> -\n> -\tutils::time_point now = std::chrono::steady_clock::now();\n> -\tif (deadline < now) {\n> -\t\tLOG(Timeline, Warning)\n> -\t\t\t<< \"Action scheduled too late \"\n> -\t\t\t<< utils::time_point_to_string(deadline)\n> -\t\t\t<< \", run now \" << utils::time_point_to_string(now);\n> -\t\taction->run();\n> -\t} else {\n> -\t\tactions_.emplace(deadline, std::move(action));\n> -\t\tupdateDeadline();\n> -\t}\n> -}\n> -\n> -void Timeline::notifyStartOfExposure(unsigned int frame, utils::time_point time)\n> -{\n> -\thistory_.push_back(std::make_pair(frame, time));\n> -\n> -\tif (history_.size() <= HISTORY_DEPTH / 2)\n> -\t\treturn;\n> -\n> -\twhile (history_.size() > HISTORY_DEPTH)\n> -\t\thistory_.pop_front();\n> -\n> -\t/* Update esitmated time between two start of exposures. */\n> -\tutils::duration sumExposures(0);\n> -\tunsigned int numExposures = 0;\n> -\n> -\tutils::time_point lastTime;\n> -\tfor (auto it = history_.begin(); it != history_.end(); it++) {\n> -\t\tif (it != history_.begin()) {\n> -\t\t\tsumExposures += it->second - lastTime;\n> -\t\t\tnumExposures++;\n> -\t\t}\n> -\n> -\t\tlastTime = it->second;\n> -\t}\n> -\n> -\tframeInterval_ = sumExposures;\n> -\tif (numExposures)\n> -\t\tframeInterval_ /= numExposures;\n> -}\n> -\n> -int Timeline::frameOffset(unsigned int type) const\n> -{\n> -\tconst auto it = delays_.find(type);\n> -\tif (it == delays_.end()) {\n> -\t\tLOG(Timeline, Error)\n> -\t\t\t<< \"No frame offset set for action type \" << type;\n> -\t\treturn 0;\n> -\t}\n> -\n> -\treturn it->second.first;\n> -}\n> -\n> -utils::duration Timeline::timeOffset(unsigned int type) const\n> -{\n> -\tconst auto it = delays_.find(type);\n> -\tif (it == delays_.end()) {\n> -\t\tLOG(Timeline, Error)\n> -\t\t\t<< \"No time offset set for action type \" << type;\n> -\t\treturn utils::duration::zero();\n> -\t}\n> -\n> -\treturn it->second.second;\n> -}\n> -\n> -void Timeline::setRawDelay(unsigned int type, int frame, utils::duration time)\n> -{\n> -\tdelays_[type] = std::make_pair(frame, time);\n> -}\n> -\n> -void Timeline::updateDeadline()\n> -{\n> -\tif (actions_.empty())\n> -\t\treturn;\n> -\n> -\tconst utils::time_point &deadline = actions_.begin()->first;\n> -\n> -\tif (timer_.isRunning() && deadline >= timer_.deadline())\n> -\t\treturn;\n> -\n> -\tif (deadline <= std::chrono::steady_clock::now()) {\n> -\t\ttimeout(&timer_);\n> -\t\treturn;\n> -\t}\n> -\n> -\ttimer_.start(deadline);\n> -}\n> -\n> -void Timeline::timeout([[maybe_unused]] Timer *timer)\n> -{\n> -\tutils::time_point now = std::chrono::steady_clock::now();\n> -\n> -\tfor (auto it = actions_.begin(); it != actions_.end();) {\n> -\t\tconst utils::time_point &sched = it->first;\n> -\n> -\t\tif (sched > now)\n> -\t\t\tbreak;\n> -\n> -\t\tFrameAction *action = it->second.get();\n> -\n> -\t\taction->run();\n> -\n> -\t\tit = actions_.erase(it);\n> -\t}\n> -\n> -\tupdateDeadline();\n> -}\n> -\n> -} /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/rkisp1/timeline.h b/src/libcamera/pipeline/rkisp1/timeline.h\n> deleted file mode 100644\n> index 35a085159b8f545b..0000000000000000\n> --- a/src/libcamera/pipeline/rkisp1/timeline.h\n> +++ /dev/null\n> @@ -1,71 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * timeline.h - Timeline for per-frame controls\n> - */\n> -#ifndef __LIBCAMERA_TIMELINE_H__\n> -#define __LIBCAMERA_TIMELINE_H__\n> -\n> -#include <list>\n> -#include <map>\n> -\n> -#include \"libcamera/internal/timer.h\"\n> -#include \"libcamera/internal/utils.h\"\n> -\n> -namespace libcamera {\n> -\n> -class FrameAction\n> -{\n> -public:\n> -\tFrameAction(unsigned int frame, unsigned int type)\n> -\t\t: frame_(frame), type_(type) {}\n> -\n> -\tvirtual ~FrameAction() = default;\n> -\n> -\tunsigned int frame() const { return frame_; }\n> -\tunsigned int type() const { return type_; }\n> -\n> -\tvirtual void run() = 0;\n> -\n> -private:\n> -\tunsigned int frame_;\n> -\tunsigned int type_;\n> -};\n> -\n> -class Timeline\n> -{\n> -public:\n> -\tTimeline();\n> -\tvirtual ~Timeline() = default;\n> -\n> -\tvirtual void reset();\n> -\tvirtual void scheduleAction(std::unique_ptr<FrameAction> action);\n> -\tvirtual void notifyStartOfExposure(unsigned int frame, utils::time_point time);\n> -\n> -\tutils::duration frameInterval() const { return frameInterval_; }\n> -\n> -protected:\n> -\tint frameOffset(unsigned int type) const;\n> -\tutils::duration timeOffset(unsigned int type) const;\n> -\n> -\tvoid setRawDelay(unsigned int type, int frame, utils::duration time);\n> -\n> -\tstd::map<unsigned int, std::pair<int, utils::duration>> delays_;\n> -\n> -private:\n> -\tstatic constexpr unsigned int HISTORY_DEPTH = 10;\n> -\n> -\tvoid timeout(Timer *timer);\n> -\tvoid updateDeadline();\n> -\n> -\tstd::list<std::pair<unsigned int, utils::time_point>> history_;\n> -\tstd::multimap<utils::time_point, std::unique_ptr<FrameAction>> actions_;\n> -\tutils::duration frameInterval_;\n> -\n> -\tTimer timer_;\n> -};\n> -\n> -} /* namespace libcamera */\n> -\n> -#endif /* __LIBCAMERA_TIMELINE_H__ */\n> --\n> 2.29.2\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E280EBE176\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 27 Nov 2020 11:06:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BC16E6346E;\n\tFri, 27 Nov 2020 12:06:10 +0100 (CET)","from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net\n\t[217.70.183.200])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7A315632EE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 27 Nov 2020 12:06:09 +0100 (CET)","from uno.localdomain (93-34-118-233.ip49.fastwebnet.it\n\t[93.34.118.233]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay7-d.mail.gandi.net (Postfix) with ESMTPSA id CF34520005;\n\tFri, 27 Nov 2020 11:06:08 +0000 (UTC)"],"X-Originating-IP":"93.34.118.233","Date":"Fri, 27 Nov 2020 12:06:14 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20201127110614.sgky3464jflvtkhm@uno.localdomain>","References":"<20201123221234.485933-1-niklas.soderlund@ragnatech.se>\n\t<20201123221234.485933-9-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201123221234.485933-9-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v3 8/8] libcamera: pipeline: rkisp1:\n\tRemove Timeline","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14069,"web_url":"https://patchwork.libcamera.org/comment/14069/","msgid":"<20201205013947.GR4109@pendragon.ideasonboard.com>","date":"2020-12-05T01:39:47","subject":"Re: [libcamera-devel] [PATCH v3 8/8] libcamera: pipeline: rkisp1:\n\tRemove Timeline","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Mon, Nov 23, 2020 at 11:12:34PM +0100, Niklas Söderlund wrote:\n> There are no users left of the Timeline and there is no longer a need to\n> keep emulating a start of exposure event as the CSI-2 resciver reports\n> it. Remove the Timeline helper and what's left of it's integration in\n> the pipeline.\n> \n> There is no functional change as nothing i the pipeline uses the\n> Timeline.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  src/libcamera/pipeline/rkisp1/meson.build  |   1 -\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp   |  45 ----\n>  src/libcamera/pipeline/rkisp1/timeline.cpp | 227 ---------------------\n>  src/libcamera/pipeline/rkisp1/timeline.h   |  71 -------\n>  4 files changed, 344 deletions(-)\n>  delete mode 100644 src/libcamera/pipeline/rkisp1/timeline.cpp\n>  delete mode 100644 src/libcamera/pipeline/rkisp1/timeline.h\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/meson.build b/src/libcamera/pipeline/rkisp1/meson.build\n> index 5cd40d949d543fa9..cad66535c25f8cc0 100644\n> --- a/src/libcamera/pipeline/rkisp1/meson.build\n> +++ b/src/libcamera/pipeline/rkisp1/meson.build\n> @@ -3,5 +3,4 @@\n>  libcamera_sources += files([\n>      'rkisp1.cpp',\n>      'rkisp1_path.cpp',\n> -    'timeline.cpp',\n>  ])\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 3662a53ac4a43fcd..c2b61e88ec34aa60 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -33,7 +33,6 @@\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n>  #include \"rkisp1_path.h\"\n> -#include \"timeline.h\"\n>  \n>  namespace libcamera {\n>  \n> @@ -42,12 +41,6 @@ LOG_DEFINE_CATEGORY(RkISP1)\n>  class PipelineHandlerRkISP1;\n>  class RkISP1CameraData;\n>  \n> -enum RkISP1ActionType {\n> -\tSetSensor,\n> -\tSOE,\n> -\tQueueBuffers,\n> -};\n> -\n>  struct RkISP1FrameInfo {\n>  \tunsigned int frame;\n>  \tRequest *request;\n> @@ -80,41 +73,6 @@ private:\n>  \tstd::map<unsigned int, RkISP1FrameInfo *> frameInfo_;\n>  };\n>  \n> -class RkISP1Timeline : public Timeline\n> -{\n> -public:\n> -\tRkISP1Timeline()\n> -\t\t: Timeline()\n> -\t{\n> -\t\tsetDelay(SetSensor, -1, 5);\n> -\t\tsetDelay(SOE, 0, -1);\n> -\t\tsetDelay(QueueBuffers, -1, 10);\n> -\t}\n> -\n> -\tvoid bufferReady(FrameBuffer *buffer)\n> -\t{\n> -\t\t/*\n> -\t\t * Calculate SOE by taking the end of DMA set by the kernel and applying\n> -\t\t * the time offsets provideprovided by the IPA to find the best estimate\n> -\t\t * of SOE.\n> -\t\t */\n> -\n> -\t\tASSERT(frameOffset(SOE) == 0);\n> -\n> -\t\tutils::time_point soe = std::chrono::time_point<utils::clock>()\n> -\t\t\t+ std::chrono::nanoseconds(buffer->metadata().timestamp)\n> -\t\t\t+ timeOffset(SOE);\n> -\n> -\t\tnotifyStartOfExposure(buffer->metadata().sequence, soe);\n> -\t}\n> -\n> -\tvoid setDelay(unsigned int type, int frame, int msdelay)\n> -\t{\n> -\t\tutils::duration delay = std::chrono::milliseconds(msdelay);\n> -\t\tsetRawDelay(type, frame, delay);\n> -\t}\n> -};\n> -\n>  class RkISP1CameraData : public CameraData\n>  {\n>  public:\n> @@ -140,7 +98,6 @@ public:\n>  \tunsigned int frame_;\n>  \tstd::vector<IPABuffer> ipaBuffers_;\n>  \tRkISP1Frames frameInfo_;\n> -\tRkISP1Timeline timeline_;\n>  \n>  \tRkISP1MainPath *mainPath_;\n>  \tRkISP1SelfPath *selfPath_;\n> @@ -887,8 +844,6 @@ void PipelineHandlerRkISP1::stop(Camera *camera)\n>  \n>  \tdata->ipa_->stop();\n>  \n> -\tdata->timeline_.reset();\n> -\n>  \tdata->frameInfo_.clear();\n>  \n>  \tfreeBuffers(camera);\n> diff --git a/src/libcamera/pipeline/rkisp1/timeline.cpp b/src/libcamera/pipeline/rkisp1/timeline.cpp\n> deleted file mode 100644\n> index 6b83bbe5b5892531..0000000000000000\n> --- a/src/libcamera/pipeline/rkisp1/timeline.cpp\n> +++ /dev/null\n> @@ -1,227 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * timeline.cpp - Timeline for per-frame control\n> - */\n> -\n> -#include \"timeline.h\"\n> -\n> -#include \"libcamera/internal/log.h\"\n> -\n> -/**\n> - * \\file timeline.h\n> - * \\brief Timeline for per-frame control\n> - */\n> -\n> -namespace libcamera {\n> -\n> -LOG_DEFINE_CATEGORY(Timeline)\n> -\n> -/**\n> - * \\class FrameAction\n> - * \\brief Action that can be schedule on a Timeline\n> - *\n> - * A frame action is an event schedule to be executed on a Timeline. A frame\n> - * action has two primal attributes a frame number and a type.\n> - *\n> - * The frame number describes the frame to which the action is associated. The\n> - * type is a numerical ID which identifies the action within the pipeline and\n> - * IPA protocol.\n> - */\n> -\n> -/**\n> - * \\class Timeline\n> - * \\brief Executor of FrameAction\n> - *\n> - * The timeline has three primary functions:\n> - *\n> - * 1. Keep track of the Start of Exposure (SOE) for every frame processed by\n> - *    the hardware. Using this information it shall keep an up-to-date estimate\n> - *    of the frame interval (time between two consecutive SOE events).\n> - *\n> - *    The estimated frame interval together with recorded SOE events are the\n> - *    foundation for how the timeline schedule FrameAction at specific points\n> - *    in time.\n> - *    \\todo Improve the frame interval estimation algorithm.\n> - *\n> - * 2. Keep track of current delays for different types of actions. The delays\n> - *    for different actions might differ during a capture session. Exposure time\n> - *    effects the over all FPS and different ISP parameters might impacts its\n> - *    processing time.\n> - *\n> - *    The action type delays shall be updated by the IPA in conjunction with\n> - *    how it changes the capture parameters.\n> - *\n> - * 3. Schedule actions on the timeline. This is the process of taking a\n> - *    FrameAction which contains an abstract description of what frame and\n> - *    what type of action it contains and turning that into an time point\n> - *    and make sure the action is executed at that time.\n> - */\n> -\n> -Timeline::Timeline()\n> -\t: frameInterval_(0)\n> -{\n> -\ttimer_.timeout.connect(this, &Timeline::timeout);\n> -}\n> -\n> -/**\n> - * \\brief Reset and stop the timeline\n> - *\n> - * The timeline needs to be reset when the timeline should no longer execute\n> - * actions. A timeline should be reset between two capture sessions to prevent\n> - * the old capture session to effect the second one.\n> - */\n> -void Timeline::reset()\n> -{\n> -\ttimer_.stop();\n> -\n> -\tactions_.clear();\n> -\thistory_.clear();\n> -}\n> -\n> -/**\n> - * \\brief Schedule an action on the timeline\n> - * \\param[in] action FrameAction to schedule\n> - *\n> - * The act of scheduling an action to the timeline is the process of taking\n> - * the properties of the action (type, frame and time offsets) and translating\n> - * that to a time point using the current values for the action type timings\n> - * value recorded in the timeline. If an action is scheduled too late, execute\n> - * it immediately.\n> - */\n> -void Timeline::scheduleAction(std::unique_ptr<FrameAction> action)\n> -{\n> -\tunsigned int lastFrame;\n> -\tutils::time_point lastTime;\n> -\n> -\tif (history_.empty()) {\n> -\t\tlastFrame = 0;\n> -\t\tlastTime = std::chrono::steady_clock::now();\n> -\t} else {\n> -\t\tlastFrame = history_.back().first;\n> -\t\tlastTime = history_.back().second;\n> -\t}\n> -\n> -\t/*\n> -\t * Calculate when the action shall be schedule by first finding out how\n> -\t * many frames in the future the action acts on and then add the actions\n> -\t * frame offset. After the spatial frame offset is found out translate\n> -\t * that to a time point by using the last estimated start of exposure\n> -\t * (SOE) as the fixed offset. Lastly add the action time offset to the\n> -\t * time point.\n> -\t */\n> -\tint frame = action->frame() - lastFrame + frameOffset(action->type());\n> -\tutils::time_point deadline = lastTime + frame * frameInterval_\n> -\t\t+ timeOffset(action->type());\n> -\n> -\tutils::time_point now = std::chrono::steady_clock::now();\n> -\tif (deadline < now) {\n> -\t\tLOG(Timeline, Warning)\n> -\t\t\t<< \"Action scheduled too late \"\n> -\t\t\t<< utils::time_point_to_string(deadline)\n> -\t\t\t<< \", run now \" << utils::time_point_to_string(now);\n> -\t\taction->run();\n> -\t} else {\n> -\t\tactions_.emplace(deadline, std::move(action));\n> -\t\tupdateDeadline();\n> -\t}\n> -}\n> -\n> -void Timeline::notifyStartOfExposure(unsigned int frame, utils::time_point time)\n> -{\n> -\thistory_.push_back(std::make_pair(frame, time));\n> -\n> -\tif (history_.size() <= HISTORY_DEPTH / 2)\n> -\t\treturn;\n> -\n> -\twhile (history_.size() > HISTORY_DEPTH)\n> -\t\thistory_.pop_front();\n> -\n> -\t/* Update esitmated time between two start of exposures. */\n> -\tutils::duration sumExposures(0);\n> -\tunsigned int numExposures = 0;\n> -\n> -\tutils::time_point lastTime;\n> -\tfor (auto it = history_.begin(); it != history_.end(); it++) {\n> -\t\tif (it != history_.begin()) {\n> -\t\t\tsumExposures += it->second - lastTime;\n> -\t\t\tnumExposures++;\n> -\t\t}\n> -\n> -\t\tlastTime = it->second;\n> -\t}\n> -\n> -\tframeInterval_ = sumExposures;\n> -\tif (numExposures)\n> -\t\tframeInterval_ /= numExposures;\n> -}\n> -\n> -int Timeline::frameOffset(unsigned int type) const\n> -{\n> -\tconst auto it = delays_.find(type);\n> -\tif (it == delays_.end()) {\n> -\t\tLOG(Timeline, Error)\n> -\t\t\t<< \"No frame offset set for action type \" << type;\n> -\t\treturn 0;\n> -\t}\n> -\n> -\treturn it->second.first;\n> -}\n> -\n> -utils::duration Timeline::timeOffset(unsigned int type) const\n> -{\n> -\tconst auto it = delays_.find(type);\n> -\tif (it == delays_.end()) {\n> -\t\tLOG(Timeline, Error)\n> -\t\t\t<< \"No time offset set for action type \" << type;\n> -\t\treturn utils::duration::zero();\n> -\t}\n> -\n> -\treturn it->second.second;\n> -}\n> -\n> -void Timeline::setRawDelay(unsigned int type, int frame, utils::duration time)\n> -{\n> -\tdelays_[type] = std::make_pair(frame, time);\n> -}\n> -\n> -void Timeline::updateDeadline()\n> -{\n> -\tif (actions_.empty())\n> -\t\treturn;\n> -\n> -\tconst utils::time_point &deadline = actions_.begin()->first;\n> -\n> -\tif (timer_.isRunning() && deadline >= timer_.deadline())\n> -\t\treturn;\n> -\n> -\tif (deadline <= std::chrono::steady_clock::now()) {\n> -\t\ttimeout(&timer_);\n> -\t\treturn;\n> -\t}\n> -\n> -\ttimer_.start(deadline);\n> -}\n> -\n> -void Timeline::timeout([[maybe_unused]] Timer *timer)\n> -{\n> -\tutils::time_point now = std::chrono::steady_clock::now();\n> -\n> -\tfor (auto it = actions_.begin(); it != actions_.end();) {\n> -\t\tconst utils::time_point &sched = it->first;\n> -\n> -\t\tif (sched > now)\n> -\t\t\tbreak;\n> -\n> -\t\tFrameAction *action = it->second.get();\n> -\n> -\t\taction->run();\n> -\n> -\t\tit = actions_.erase(it);\n> -\t}\n> -\n> -\tupdateDeadline();\n> -}\n> -\n> -} /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/rkisp1/timeline.h b/src/libcamera/pipeline/rkisp1/timeline.h\n> deleted file mode 100644\n> index 35a085159b8f545b..0000000000000000\n> --- a/src/libcamera/pipeline/rkisp1/timeline.h\n> +++ /dev/null\n> @@ -1,71 +0,0 @@\n> -/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> -/*\n> - * Copyright (C) 2019, Google Inc.\n> - *\n> - * timeline.h - Timeline for per-frame controls\n> - */\n> -#ifndef __LIBCAMERA_TIMELINE_H__\n> -#define __LIBCAMERA_TIMELINE_H__\n> -\n> -#include <list>\n> -#include <map>\n> -\n> -#include \"libcamera/internal/timer.h\"\n> -#include \"libcamera/internal/utils.h\"\n> -\n> -namespace libcamera {\n> -\n> -class FrameAction\n> -{\n> -public:\n> -\tFrameAction(unsigned int frame, unsigned int type)\n> -\t\t: frame_(frame), type_(type) {}\n> -\n> -\tvirtual ~FrameAction() = default;\n> -\n> -\tunsigned int frame() const { return frame_; }\n> -\tunsigned int type() const { return type_; }\n> -\n> -\tvirtual void run() = 0;\n> -\n> -private:\n> -\tunsigned int frame_;\n> -\tunsigned int type_;\n> -};\n> -\n> -class Timeline\n> -{\n> -public:\n> -\tTimeline();\n> -\tvirtual ~Timeline() = default;\n> -\n> -\tvirtual void reset();\n> -\tvirtual void scheduleAction(std::unique_ptr<FrameAction> action);\n> -\tvirtual void notifyStartOfExposure(unsigned int frame, utils::time_point time);\n> -\n> -\tutils::duration frameInterval() const { return frameInterval_; }\n> -\n> -protected:\n> -\tint frameOffset(unsigned int type) const;\n> -\tutils::duration timeOffset(unsigned int type) const;\n> -\n> -\tvoid setRawDelay(unsigned int type, int frame, utils::duration time);\n> -\n> -\tstd::map<unsigned int, std::pair<int, utils::duration>> delays_;\n> -\n> -private:\n> -\tstatic constexpr unsigned int HISTORY_DEPTH = 10;\n> -\n> -\tvoid timeout(Timer *timer);\n> -\tvoid updateDeadline();\n> -\n> -\tstd::list<std::pair<unsigned int, utils::time_point>> history_;\n> -\tstd::multimap<utils::time_point, std::unique_ptr<FrameAction>> actions_;\n> -\tutils::duration frameInterval_;\n> -\n> -\tTimer timer_;\n> -};\n> -\n> -} /* namespace libcamera */\n> -\n> -#endif /* __LIBCAMERA_TIMELINE_H__ */","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4A361BE177\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat,  5 Dec 2020 01:39:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 10194635F1;\n\tSat,  5 Dec 2020 02:39:51 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 79F5F60325\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  5 Dec 2020 02:39:49 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0C2532A4;\n\tSat,  5 Dec 2020 02:39:48 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"irL/d6q2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1607132389;\n\tbh=TiVHSFbsfwpnI+NHyRGHUMTEdXFRUbkb8/0xOfYT0Lc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=irL/d6q2vxXQPzP6YbvoB43yS9ZGWphdS0+8Zy/ZEkU2Li4iuOCIrevcqwmqNdYbh\n\tf5+mXDGrkf/9EvfbIbyHM8Glu557zTJmEEoq5Sg/cLDObUvHcAZsR7oVNdOq7mdDNm\n\tHm5iCZKVitOhDHJj6YPEJY6yKPSjmjiaof8SQsvI=","Date":"Sat, 5 Dec 2020 03:39:47 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20201205013947.GR4109@pendragon.ideasonboard.com>","References":"<20201123221234.485933-1-niklas.soderlund@ragnatech.se>\n\t<20201123221234.485933-9-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201123221234.485933-9-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v3 8/8] libcamera: pipeline: rkisp1:\n\tRemove Timeline","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]