scar-chat7/client/media/screen_capture.h

102 lines
2.7 KiB
C++

#pragma once
#include <memory>
#include <functional>
#include <vector>
#include <string>
#ifdef __linux__
#include <spa/utils/hook.h>
#include <spa/pod/pod.h>
#endif
// Forward declarations for Pipewire/sdbus to avoid header pollution
struct pw_thread_loop;
struct pw_stream;
struct pw_context;
namespace sdbus {
class IConnection;
class IProxy;
}
namespace scar {
enum class ScreenCaptureBackend {
FFMPEG_X11, // X11 via ffmpeg
FFMPEG_WAYLAND, // Wayland via ffmpeg + portal
FFMPEG_WINDOWS, // Windows GDI via ffmpeg
PORTAL_PIPEWIRE // xdg-desktop-portal + Pipewire (Wayland/Hyprland)
};
// Screen capture supporting multiple backends
class ScreenCapture {
public:
ScreenCapture();
~ScreenCapture();
// Auto-detect and start screen capture
bool start();
// Start with specific backend
bool start(ScreenCaptureBackend backend);
// Stop capturing
void stop();
// Check if currently capturing
bool isCapturing() const { return capturing_; }
// Set frame callback
using FrameCallback = std::function<void(const std::vector<uint8_t>& frameData, int width, int height)>;
void setFrameCallback(FrameCallback callback);
private:
ScreenCaptureBackend detectBestBackend();
bool startX11Capture();
bool startWaylandCapture();
bool startWindowsCapture();
bool startPortalCapture();
// sdbus Portal methods
bool initPortalConnection();
void cleanupPortalConnection();
std::string createPortalSession();
bool selectPortalSources(const std::string& session_handle);
bool startPortalSession(const std::string& session_handle, uint32_t& node_id);
int openPipeWireRemote(const std::string& session_handle);
uint32_t getStreamsNodeId(const std::string& session_handle);
// Pipewire methods
bool initPipewire(int fd, uint32_t node_id);
void cleanupPipewire();
static void onStreamProcess(void* userdata);
static void onStreamParamChanged(void* userdata, uint32_t id, const struct spa_pod* param);
bool capturing_;
ScreenCaptureBackend backend_;
FrameCallback frameCallback_;
// sdbus members
std::shared_ptr<sdbus::IConnection> portal_connection_;
std::unique_ptr<sdbus::IProxy> screencast_proxy_;
std::string session_path_;
// Pipewire members
pw_thread_loop* pw_loop_;
pw_stream* pw_stream_;
pw_context* pw_context_;
spa_hook stream_listener_;
int frame_width_;
int frame_height_;
// TODO: FFmpeg-specific members
// AVFormatContext* formatCtx_;
// AVCodecContext* codecCtx_;
// AVFrame* frame_;
};
} // namespace scar