Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial frame notif acc to kpi #10147

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 60 additions & 4 deletions src/linux/backend-v4l2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#pragma GCC diagnostic ignored "-Woverflow"

const size_t MAX_DEV_PARENT_DIR = 10;
const double DEFAULT_KPI_FRAME_DROPS_PERCENTAGE = 0.05;

#include "../tm2/tm-boot.h"

Expand Down Expand Up @@ -678,6 +679,56 @@ namespace librealsense
}
}

bool kpi_checker::update_and_check(const stream_profile& profile, const timeval& timestamp)
{
bool is_kpi_violated = false;
long int timestamp_usec = static_cast<long int> (timestamp.tv_sec * 1000000 + timestamp.tv_usec);

// checking if the current profile is already in the drops_per_stream container
auto it = std::find_if(drops_per_stream.begin(), drops_per_stream.end(),
remibettan marked this conversation as resolved.
Show resolved Hide resolved
[profile](std::pair<stream_profile, std::deque<long int>>& sp_deq)
{return profile == sp_deq.first; });

// if the profile is already in the drops_per_stream container,
// checking kpi with the new partial frame caught
if (it != drops_per_stream.end())
{
// setting the kpi checking to be done on the last 2 seconds
int time_limit = 2;
// max number of drops that can be received in the time_limit, without violation of the kpi
int max_num_of_drops = profile.fps * _kpi_frames_drops_pct * time_limit;

auto& queue_for_profile = it->second;
// removing too old timestamps of partial frames
while (queue_for_profile.size() > 0)
{
auto delta_ts_usec = timestamp_usec - queue_for_profile.front();
if (delta_ts_usec > (time_limit * 1000000))
{
queue_for_profile.pop_front();
}
else
break; // correct because the frames are added chronologically
}
// checking kpi violation
if (queue_for_profile.size() >= max_num_of_drops)
{
is_kpi_violated = true;
queue_for_profile.clear();
}
else
queue_for_profile.push_back(timestamp_usec);
}
else
{
// adding the the current partial frame's profile and timestamp to the container
std::deque<long int> deque_to_add;
deque_to_add.push_back(timestamp_usec);
drops_per_stream.push_back(std::make_pair(profile, deque_to_add));
}
return is_kpi_violated;
}

v4l_uvc_device::v4l_uvc_device(const uvc_device_info& info, bool use_memory_map)
: _name(""), _info(),
_is_capturing(false),
Expand All @@ -688,7 +739,8 @@ namespace librealsense
_use_memory_map(use_memory_map),
_fd(-1),
_stop_pipe_fd{},
_buf_dispatch(use_memory_map)
_buf_dispatch(use_memory_map),
_kpi_checker(DEFAULT_KPI_FRAME_DROPS_PERCENTAGE)
{
foreach_uvc_device([&info, this](const uvc_device_info& i, const std::string& name)
{
Expand Down Expand Up @@ -1060,9 +1112,13 @@ namespace librealsense
<< ", payload size " << buffer->get_length_frame_only();
}
LOG_WARNING("Incomplete frame received: " << s.str()); // Ev -try1
remibettan marked this conversation as resolved.
Show resolved Hide resolved
librealsense::notification n = { RS2_NOTIFICATION_CATEGORY_FRAME_CORRUPTED, 0, RS2_LOG_SEVERITY_WARN, s.str()};

_error_handler(n);
bool kpi_violated = _kpi_checker.update_and_check(_profile, buf.timestamp);
if (kpi_violated)
remibettan marked this conversation as resolved.
Show resolved Hide resolved
{
librealsense::notification n = { RS2_NOTIFICATION_CATEGORY_FRAME_CORRUPTED, 0, RS2_LOG_SEVERITY_WARN, s.str() };
_error_handler(n);
}

// Check if metadata was already allocated
if (buf_mgr.metadata_size())
{
Expand Down
21 changes: 21 additions & 0 deletions src/linux/backend-v4l2.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,26 @@ namespace librealsense
virtual void acquire_metadata(buffers_mgr & buf_mgr,fd_set &fds, bool compressed_format) = 0;
};

// The aim of the kpi checker is to check the frames drops kpi - which requires
// that no more than some percentage of the frames are dropped
// It is checked using the fps, and the previous corrupted frames, on the last 2 seconds
// for example, for frame rate of 30 fps, and kpi of 5%, the criteria will be:
// if at least 3 frames (= 30[fps] * 5%[kpi]* 2[sec]) drops have occured in the 2 seconds,
// then the kpi is violated
class kpi_checker
remibettan marked this conversation as resolved.
Show resolved Hide resolved
{
public:
kpi_checker(double kpi_frames_drops_percentage) : _kpi_frames_drops_pct(kpi_frames_drops_percentage) {}
// update_and_check method returns whether the kpi has been violated
// it should be called each time a partial frame is caught
bool update_and_check(const stream_profile& profile, const timeval& timestamp);

private:
// container used to store the latest timestamps of the partial frames, per profile
std::vector<std::pair<stream_profile, std::deque<long int>>> drops_per_stream;
remibettan marked this conversation as resolved.
Show resolved Hide resolved
double _kpi_frames_drops_pct;
};

class v4l_uvc_device : public uvc_device, public v4l_uvc_interface
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with kernel 5+: the 'v4l_uvc_device' class may not apply there

{
public:
Expand Down Expand Up @@ -341,6 +361,7 @@ namespace librealsense
int _max_fd = 0; // specifies the maximal pipe number the polling process will monitor
std::vector<int> _fds; // list the file descriptors to be monitored during frames polling
buffers_mgr _buf_dispatch; // Holder for partial (MD only) frames that shall be preserved between 'select' calls when polling v4l buffers
kpi_checker _kpi_checker; // used to check the frames drops kpi

private:
int _fd = 0; // prevent unintentional abuse in derived class
Expand Down