Extend packet header with frame processing latency
This commit is contained in:
@@ -186,6 +186,8 @@ namespace platf {
|
||||
std::int32_t pixel_pitch {};
|
||||
std::int32_t row_pitch {};
|
||||
|
||||
std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
|
||||
|
||||
virtual ~img_t() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// #include <algorithm>
|
||||
#include <helper_math.h>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -31,8 +32,10 @@ using namespace std::literals;
|
||||
|
||||
//////////////////// Special desclarations
|
||||
/**
|
||||
* NVCC segfaults when including <chrono>
|
||||
* Therefore, some declarations need to be added explicitely
|
||||
* NVCC tends to have problems with standard headers.
|
||||
* Don't include common.h, instead use bare minimum
|
||||
* of standard headers and duplicate declarations of necessary classes.
|
||||
* Not pretty and extremely error-prone, fix at earliest convenience.
|
||||
*/
|
||||
namespace platf {
|
||||
struct img_t: std::enable_shared_from_this<img_t> {
|
||||
@@ -43,6 +46,8 @@ public:
|
||||
std::int32_t pixel_pitch {};
|
||||
std::int32_t row_pitch {};
|
||||
|
||||
std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
|
||||
|
||||
virtual ~img_t() = default;
|
||||
};
|
||||
} // namespace platf
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "display.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "src/main.h"
|
||||
|
||||
namespace platf {
|
||||
@@ -192,6 +194,12 @@ namespace platf::dxgi {
|
||||
return capture_e::timeout;
|
||||
}
|
||||
|
||||
std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
|
||||
if (auto qpc_displayed = std::max(frame_info.LastPresentTime.QuadPart, frame_info.LastMouseUpdateTime.QuadPart)) {
|
||||
// Translate QueryPerformanceCounter() value to steady_clock time point
|
||||
frame_timestamp = std::chrono::steady_clock::now() - qpc_time_difference(qpc_counter(), qpc_displayed);
|
||||
}
|
||||
|
||||
if (frame_info.PointerShapeBufferSize > 0) {
|
||||
auto &img_data = cursor.img_data;
|
||||
|
||||
@@ -307,6 +315,10 @@ namespace platf::dxgi {
|
||||
blend_cursor(cursor, *img);
|
||||
}
|
||||
|
||||
if (img) {
|
||||
img->frame_timestamp = frame_timestamp;
|
||||
}
|
||||
|
||||
return capture_e::ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "display.h"
|
||||
#include "misc.h"
|
||||
#include "src/main.h"
|
||||
#include "src/video.h"
|
||||
|
||||
@@ -894,6 +895,12 @@ namespace platf::dxgi {
|
||||
return capture_e::timeout;
|
||||
}
|
||||
|
||||
std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
|
||||
if (auto qpc_displayed = std::max(frame_info.LastPresentTime.QuadPart, frame_info.LastMouseUpdateTime.QuadPart)) {
|
||||
// Translate QueryPerformanceCounter() value to steady_clock time point
|
||||
frame_timestamp = std::chrono::steady_clock::now() - qpc_time_difference(qpc_counter(), qpc_displayed);
|
||||
}
|
||||
|
||||
if (frame_info.PointerShapeBufferSize > 0) {
|
||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info {};
|
||||
|
||||
@@ -1239,6 +1246,10 @@ namespace platf::dxgi {
|
||||
old_surface_delayed_destruction.reset();
|
||||
}
|
||||
|
||||
if (img_out) {
|
||||
img_out->frame_timestamp = frame_timestamp;
|
||||
}
|
||||
|
||||
return capture_e::ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -1020,4 +1020,25 @@ namespace platf {
|
||||
|
||||
return std::make_unique<qos_t>(flow_id);
|
||||
}
|
||||
int64_t
|
||||
qpc_counter() {
|
||||
LARGE_INTEGER performace_counter;
|
||||
if (QueryPerformanceCounter(&performace_counter)) return performace_counter.QuadPart;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds
|
||||
qpc_time_difference(int64_t performance_counter1, int64_t performance_counter2) {
|
||||
auto get_frequency = []() {
|
||||
LARGE_INTEGER frequency;
|
||||
frequency.QuadPart = 0;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return frequency.QuadPart;
|
||||
};
|
||||
static const double frequency = get_frequency();
|
||||
if (frequency) {
|
||||
return std::chrono::nanoseconds((int64_t) ((performance_counter1 - performance_counter2) * frequency / std::nano::den));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
} // namespace platf
|
||||
@@ -1,5 +1,7 @@
|
||||
#ifndef SUNSHINE_WINDOWS_MISC_H
|
||||
#define SUNSHINE_WINDOWS_MISC_H
|
||||
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
@@ -9,6 +11,12 @@ namespace platf {
|
||||
print_status(const std::string_view &prefix, HRESULT status);
|
||||
HDESK
|
||||
syncThreadDesktop();
|
||||
|
||||
int64_t
|
||||
qpc_counter();
|
||||
|
||||
std::chrono::nanoseconds
|
||||
qpc_time_difference(int64_t performance_counter1, int64_t performance_counter2);
|
||||
} // namespace platf
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user