fix(linux/wlgrab): add frame_timestamp using wayland's ready timestamp (#4787)
Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
This commit is contained in:
@@ -29,7 +29,18 @@ namespace wl {
|
||||
class wlr_t: public platf::display_t {
|
||||
public:
|
||||
int init(platf::mem_type_e hwdevice_type, const std::string &display_name, const ::video::config_t &config) {
|
||||
delay = std::chrono::nanoseconds {1s} / config.framerate;
|
||||
// calculate frame interval we should capture at
|
||||
if (config.framerateX100 > 0) {
|
||||
AVRational fps_strict = ::video::framerateX100_to_rational(config.framerateX100);
|
||||
delay = std::chrono::nanoseconds(
|
||||
(static_cast<int64_t>(fps_strict.den) * 1'000'000'000LL) / fps_strict.num
|
||||
);
|
||||
BOOST_LOG(info) << "[wlgrab] Requested frame rate [" << fps_strict.num << "/" << fps_strict.den << ", approx. " << av_q2d(fps_strict) << " fps]";
|
||||
} else {
|
||||
delay = std::chrono::nanoseconds {1s} / config.framerate;
|
||||
BOOST_LOG(info) << "[wlgrab] Requested frame rate [" << config.framerate << "fps]";
|
||||
}
|
||||
|
||||
mem_type = hwdevice_type;
|
||||
|
||||
if (display.init()) {
|
||||
@@ -41,12 +52,12 @@ namespace wl {
|
||||
display.roundtrip();
|
||||
|
||||
if (!interface[wl::interface_t::XDG_OUTPUT]) {
|
||||
BOOST_LOG(error) << "Missing Wayland wire for xdg_output"sv;
|
||||
BOOST_LOG(error) << "[wlgrab] Missing Wayland wire for xdg_output"sv;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!interface[wl::interface_t::WLR_EXPORT_DMABUF]) {
|
||||
BOOST_LOG(error) << "Missing Wayland wire for wlr-export-dmabuf"sv;
|
||||
BOOST_LOG(error) << "[wlgrab] Missing Wayland wire for wlr-export-dmabuf"sv;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -88,12 +99,12 @@ namespace wl {
|
||||
this->env_logical_width = desktop_logical_width;
|
||||
this->env_logical_height = desktop_logical_height;
|
||||
|
||||
BOOST_LOG(info) << "Selected monitor ["sv << monitor->description << "] for streaming"sv;
|
||||
BOOST_LOG(debug) << "Offset: "sv << offset_x << 'x' << offset_y;
|
||||
BOOST_LOG(debug) << "Resolution: "sv << width << 'x' << height;
|
||||
BOOST_LOG(debug) << "Logical Resolution: "sv << logical_width << 'x' << logical_height;
|
||||
BOOST_LOG(debug) << "Desktop Resolution: "sv << env_width << 'x' << env_height;
|
||||
BOOST_LOG(debug) << "Logical Desktop Resolution: "sv << env_logical_width << 'x' << env_logical_height;
|
||||
BOOST_LOG(info) << "[wlgrab] Selected monitor ["sv << monitor->description << "] for streaming"sv;
|
||||
BOOST_LOG(debug) << "[wlgrab] Offset: "sv << offset_x << 'x' << offset_y;
|
||||
BOOST_LOG(debug) << "[wlgrab] Resolution: "sv << width << 'x' << height;
|
||||
BOOST_LOG(debug) << "[wlgrab] Logical Resolution: "sv << logical_width << 'x' << logical_height;
|
||||
BOOST_LOG(debug) << "[wlgrab] Desktop Resolution: "sv << env_width << 'x' << env_height;
|
||||
BOOST_LOG(debug) << "[wlgrab] Logical Desktop Resolution: "sv << env_logical_width << 'x' << env_logical_height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -177,7 +188,7 @@ namespace wl {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int) status << ']';
|
||||
BOOST_LOG(error) << "[wlgrab] Unrecognized capture status ["sv << std::to_underlying(status) << ']';
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -210,11 +221,13 @@ namespace wl {
|
||||
int w;
|
||||
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
gl::ctx.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
BOOST_LOG(debug) << "width and height: w "sv << w << " h "sv << h;
|
||||
BOOST_LOG(debug) << "[wlgrab] width and height: w "sv << w << " h "sv << h;
|
||||
|
||||
gl::ctx.GetTextureSubImage((*rgb_opt)->tex[0], 0, 0, 0, 0, width, height, 1, GL_BGRA, GL_UNSIGNED_BYTE, img_out->height * img_out->row_pitch, img_out->data);
|
||||
gl::ctx.BindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
img_out->frame_timestamp = current_frame->frame_timestamp;
|
||||
|
||||
return platf::capture_e::ok;
|
||||
}
|
||||
|
||||
@@ -308,7 +321,7 @@ namespace wl {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BOOST_LOG(error) << "Unrecognized capture status ["sv << (int) status << ']';
|
||||
BOOST_LOG(error) << "[wlgrab] Unrecognized capture status ["sv << std::to_underlying(status) << ']';
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -334,6 +347,7 @@ namespace wl {
|
||||
img->sequence = sequence;
|
||||
|
||||
img->sd = current_frame->sd;
|
||||
img->frame_timestamp = current_frame->frame_timestamp;
|
||||
|
||||
// Prevent dmabuf from closing the file descriptors.
|
||||
std::fill_n(current_frame->sd.fds, 4, -1);
|
||||
@@ -385,7 +399,7 @@ namespace wl {
|
||||
namespace platf {
|
||||
std::shared_ptr<display_t> wl_display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
|
||||
if (hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) {
|
||||
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
|
||||
BOOST_LOG(error) << "[wlgrab] Could not initialize display with the given hw device type."sv;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -420,12 +434,12 @@ namespace platf {
|
||||
display.roundtrip();
|
||||
|
||||
if (!interface[wl::interface_t::XDG_OUTPUT]) {
|
||||
BOOST_LOG(warning) << "Missing Wayland wire for xdg_output"sv;
|
||||
BOOST_LOG(warning) << "[wlgrab] Missing Wayland wire for xdg_output"sv;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!interface[wl::interface_t::WLR_EXPORT_DMABUF]) {
|
||||
BOOST_LOG(warning) << "Missing Wayland wire for wlr-export-dmabuf"sv;
|
||||
BOOST_LOG(warning) << "[wlgrab] Missing Wayland wire for wlr-export-dmabuf"sv;
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -438,20 +452,20 @@ namespace platf {
|
||||
|
||||
display.roundtrip();
|
||||
|
||||
BOOST_LOG(info) << "-------- Start of Wayland monitor list --------"sv;
|
||||
BOOST_LOG(info) << "[wlgrab] -------- Start of Wayland monitor list --------"sv;
|
||||
|
||||
for (int x = 0; x < interface.monitors.size(); ++x) {
|
||||
auto monitor = interface.monitors[x].get();
|
||||
|
||||
wl::env_width = std::max(wl::env_width, (int) (monitor->viewport.offset_x + monitor->viewport.width));
|
||||
wl::env_height = std::max(wl::env_height, (int) (monitor->viewport.offset_y + monitor->viewport.height));
|
||||
wl::env_width = std::max(wl::env_width, monitor->viewport.offset_x + monitor->viewport.width);
|
||||
wl::env_height = std::max(wl::env_height, monitor->viewport.offset_y + monitor->viewport.height);
|
||||
|
||||
BOOST_LOG(info) << "Monitor " << x << " is "sv << monitor->name << ": "sv << monitor->description;
|
||||
BOOST_LOG(info) << "[wlgrab] Monitor " << x << " is "sv << monitor->name << ": "sv << monitor->description;
|
||||
|
||||
display_names.emplace_back(std::to_string(x));
|
||||
}
|
||||
|
||||
BOOST_LOG(info) << "--------- End of Wayland monitor list ---------"sv;
|
||||
BOOST_LOG(info) << "[wlgrab] --------- End of Wayland monitor list ---------"sv;
|
||||
|
||||
return display_names;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user