diff --git a/remote_desk_gui/main.cpp b/remote_desk_gui/main.cpp index f606b7c..090da93 100644 --- a/remote_desk_gui/main.cpp +++ b/remote_desk_gui/main.cpp @@ -26,6 +26,9 @@ #include extern "C" { +#include +#include +#include #include #include #include @@ -35,7 +38,11 @@ extern "C" { #include "imgui_impl_sdl2.h" #include "imgui_impl_sdlrenderer2.h" #include "log.h" +#ifdef _WIN32 #include "screen_capture_wgc.h" +#elif __linux__ +#include "screen_capture_x11.h" +#endif #include "x.h" #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 @@ -74,10 +81,14 @@ bool received_frame = false; static bool connect_button_pressed = false; static const char *connect_label = "Connect"; +#ifdef _WIN32 ScreenCaptureWgc *screen_capture = nullptr; +#elif __linux__ +ScreenCaptureX11 *screen_capture = nullptr; +#endif -char *nv12_buffer_ = nullptr; -std::chrono::steady_clock::time_point last_frame_time_; +char *nv12_buffer = nullptr; +std::chrono::_V2::system_clock::time_point last_frame_time_; typedef enum { mouse = 0, keyboard } ControlType; typedef enum { move = 0, left_down, left_up, right_down, right_up } MouseFlag; @@ -527,7 +538,7 @@ int main() { if (strcmp(online_label, "Online") == 0) { CreateConnection(peer_server, mac_addr, server_password); - nv12_buffer_ = new char[NV12_BUFFER_SIZE]; + nv12_buffer = new char[NV12_BUFFER_SIZE]; #ifdef _WIN32 screen_capture = new ScreenCaptureWgc(); @@ -549,9 +560,38 @@ int main() { if (tc >= 0) { BGRAToNV12FFmpeg(data, width, height, - (unsigned char *)nv12_buffer_); + (unsigned char *)nv12_buffer); SendData(peer_server, DATA_TYPE::VIDEO, - (const char *)nv12_buffer_, NV12_BUFFER_SIZE); + (const char *)nv12_buffer, NV12_BUFFER_SIZE); + // std::cout << "Send" << std::endl; + last_frame_time_ = now_time; + } + }); + + screen_capture->Start(); + +#elif __linux__ + screen_capture = new ScreenCaptureX11(); + + RECORD_DESKTOP_RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = 0; + rect.bottom = 0; + + last_frame_time_ = std::chrono::high_resolution_clock::now(); + screen_capture->Init( + rect, 60, + [](unsigned char *data, int size, int width, + int height) -> void { + auto now_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration duration = + now_time - last_frame_time_; + auto tc = duration.count() * 1000; + + if (tc >= 0) { + SendData(peer_server, DATA_TYPE::VIDEO, + (const char *)nv12_buffer, NV12_BUFFER_SIZE); // std::cout << "Send" << std::endl; last_frame_time_ = now_time; } diff --git a/screen_capture/linux/screen_capture_x11.cpp b/screen_capture/linux/screen_capture_x11.cpp index da5cf55..b004d0c 100644 --- a/screen_capture/linux/screen_capture_x11.cpp +++ b/screen_capture/linux/screen_capture_x11.cpp @@ -11,16 +11,20 @@ ScreenCaptureX11::~ScreenCaptureX11() {} int ScreenCaptureX11::Init(const RECORD_DESKTOP_RECT &rect, const int fps, cb_desktop_data cb) { + if (cb) { + _on_data = cb; + } + pFormatCtx_ = avformat_alloc_context(); avdevice_register_all(); // grabbing frame rate - av_dict_set(&options_, "framerate", "5", 0); + av_dict_set(&options_, "framerate", "30", 0); // Make the grabbed area follow the mouse av_dict_set(&options_, "follow_mouse", "centered", 0); // Video frame size. The default is to capture the full screen - av_dict_set(&options_, "video_size", "1280x720", 0); + // av_dict_set(&options_, "video_size", "1280x720", 0); ifmt_ = (AVInputFormat *)av_find_input_format("x11grab"); if (!ifmt_) { printf("Couldn't find_input_format\n"); @@ -103,6 +107,10 @@ int ScreenCaptureX11::Start() { sws_scale(img_convert_ctx_, pFrame_->data, pFrame_->linesize, 0, pFrame_->height, pFrameNV12_->data, pFrameNV12_->linesize); + + _on_data((unsigned char *)nv12_buffer_, + pFrame_->width * pFrame_->height * 3 / 2, pFrame_->width, + pFrame_->height); } } } diff --git a/screen_capture/linux/x11_session_impl.cpp b/screen_capture/linux/x11_session_impl.cpp index b448d86..d773e25 100644 --- a/screen_capture/linux/x11_session_impl.cpp +++ b/screen_capture/linux/x11_session_impl.cpp @@ -38,14 +38,12 @@ int X11SessionImpl::Start() { int X11SessionImpl::Stop() { return 0; } -int X11SessionImpl::Pause() {} +int X11SessionImpl::Pause() { return 0; } -int X11SessionImpl::Resume() {} +int X11SessionImpl::Resume() { return 0; } void X11SessionImpl::OnFrame() {} void X11SessionImpl::OnClosed() {} -int X11SessionImpl::Initialize() { return 0; } - void X11SessionImpl::CleanUp() {} \ No newline at end of file diff --git a/screen_capture/linux/x11_session_impl.h b/screen_capture/linux/x11_session_impl.h index c5c8472..075c174 100644 --- a/screen_capture/linux/x11_session_impl.h +++ b/screen_capture/linux/x11_session_impl.h @@ -28,7 +28,6 @@ class X11SessionImpl : public X11Session { void OnFrame(); void OnClosed(); - int Initialize(); void CleanUp(); // void message_func(); diff --git a/xmake.lua b/xmake.lua index 950bafd..77d12e0 100644 --- a/xmake.lua +++ b/xmake.lua @@ -38,7 +38,7 @@ target("log") target("screen_capture") set_kind("static") - add_packages("log") + add_packages("log", "ffmpeg") if is_os("windows") then add_files("screen_capture/windows/*.cpp") add_includedirs("screen_capture/windows", {public = true}) @@ -63,4 +63,9 @@ target("remote_desk") add_links("SDL2") elseif is_os("linux") then add_links("SDL2") + -- add_ldflags("-lsndio", "-lasound", "-lxcb", "-lX11", "-lXext", "-lXv", + -- "-lxcb-shape", "-lxcb-xfixes", "-lxcb-shm", "-lavfilter", "-ldl", + -- "-lavdevice", "-lavformat", "-lavcodec", "-lswscale", "-lswresample", + -- "-lavutil", {force = true}) + -- -- add_ldflags("-lasound", "-lX11", "-lXext", "-lxcb", "-lsndio", "-lpostproc", "-ldl", {force = true}) end \ No newline at end of file