Skip to content

[WIP] Create backend abstraction layer and feature detection setup#32

Closed
Copilot wants to merge 1 commit intomainfrom
copilot/create-backend-abstraction-layer
Closed

[WIP] Create backend abstraction layer and feature detection setup#32
Copilot wants to merge 1 commit intomainfrom
copilot/create-backend-abstraction-layer

Conversation

Copy link
Contributor

Copilot AI commented Feb 12, 2026

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

PHASE 0: Backend Infrastructure & Feature Detection Setup

Goal

Create the foundational abstraction layer and infrastructure that enables all subsequent fallback phases (1-6) to plug in seamlessly. This phase establishes:

  1. Backend abstraction structs for each subsystem
  2. Generic fallback selection mechanism
  3. Feature detection & availability checking
  4. Runtime reporting of active backends
  5. Configuration system for backend overrides

Problem

Currently, each subsystem initializes differently with hard-coded error exits:

// Current: Hard-coded, no fallback
if (rootstream_capture_init(ctx) < 0) {
    fprintf(stderr, "ERROR: Capture init failed\n");
    return -1;  // FATAL - no alternatives tried
}

This makes adding fallbacks (Phase 1-6) messy and inconsistent across the codebase.

Solution: Unified Backend Abstraction Layer

1. Define Backend Abstraction Structs

Add to include/rootstream.h:

/* ============================================================================
 * BACKEND ABSTRACTION LAYER
 * ============================================================================
 * 
 * Each subsystem (capture, encode, audio, etc.) can have multiple implementations.
 * This allows runtime selection, fallback on failure, and easy testing.
 */

/* Generic backend interface */
typedef struct {
    const char *name;                          /* User-friendly name */
    const char *description;                   /* Short description */
    
    /* Initialization & cleanup */
    int (*init_fn)(rootstream_ctx_t *ctx);    /* Return 0 on success */
    void (*cleanup_fn)(rootstream_ctx_t *ctx);
    
    /* Availability check (optional) */
    bool (*available_fn)(void);                /* Return true if available on this system */
    
    /* Metadata */
    int priority;                              /* 0=highest priority, higher=lower */
    bool required;                             /* true=must succeed, false=optional */
} backend_t;

/* Display capture backends */
typedef struct {
    backend_t base;
    int (*capture_frame_fn)(rootstream_ctx_t *ctx, frame_buffer_t *frame);
    void (*set_region_fn)(rootstream_ctx_t *ctx, int x, int y, int w, int h);  /* Optional */
} capture_backend_t;

/* Video encoder backends */
typedef struct {
    backend_t base;
    int (*encode_fn)(rootstream_ctx_t *ctx, frame_buffer_t *in, 
                     uint8_t *out, size_t *out_size);
    int (*encode_ex_fn)(rootstream_ctx_t *ctx, frame_buffer_t *in,
                        uint8_t *out, size_t *out_size, bool *is_keyframe);
    const char *supported_codecs[4];           /* CODEC_H264, CODEC_H265, NULL */
} encoder_backend_t;

/* Audio capture backends */
typedef struct {
    backend_t base;
    int (*capture_frame_fn)(rootstream_ctx_t *ctx, int16_t *samples, size_t *num_samples);
    int sample_rate;                           /* e.g., 48000 */
    int channels;                              /* e.g., 2 (stereo) */
} audio_capture_backend_t;

/* Audio playback backends */
typedef struct {
    backend_t base;
    int (*playback_fn)(rootstream_ctx_t *ctx, const int16_t *samples, size_t num_samples);
    int sample_rate;
    int channels;
} audio_playback_backend_t;

/* Network transport backends */
typedef struct {
    backend_t base;
    int (*send_fn)(rootstream_ctx_t *ctx, peer_t *peer, const uint8_t *data, size_t size);
    int (*recv_fn)(rootstream_ctx_t *ctx, int timeout_ms);
    int (*handshake_fn)(rootstream_ctx_t *ctx, peer_t *peer);
} network_backend_t;

/* Discovery backends */
typedef struct {
    backend_t base;
    int (*announce_fn)(rootstream_ctx_t *ctx);
    int (*browse_fn)(rootstream_ctx_t *ctx);
    int (*resolve_fn)(const char *service_name, char *hostname, uint16_t *port);
} discovery_backend_t;

/* Input injection backends */
typedef struct {
    backend_t base;
    int (*inject_key_fn)(uint32_t key, bool press);
    int (*inject_mouse_fn)(int x, int y, uint32_t buttons);
    int (*inject_gamepad_fn)(const gamepad_state_t *state);
} input_backend_t;

2. Add Backend Tracking to Context

Add to rootstream_ctx_t in include/rootstream.h:

typedef struct {
    /* Active backends (selected at runtime) */
    const capture_backend_t *capture;
    const encoder_backend_t *encoder;
    const audio_capture_backend_t *audio_capture;
    const audio_playback_backend_t *audio_playback;
    const network_backend_t *network;
    const discovery_backend_t *discovery;
    const input_backend_t *input;
    
    /* Feature availability report */
    struct {
        bool capture_drm;
        bool capture_x11;
        bool capture_pipewire;
        bool capture_dummy;
        
        bool encode_nvenc;
        bool encode_vaapi;
        bool encode_ffmpeg;
        bool encode_raw;
        
        bool audio_alsa;
        bool audio_pulse;
        bool audio_dummy;
        
        bool network_udp;
        bool network_tcp;
        bool network_relay;
        
        bool ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

@infinityabundance infinityabundance deleted the copilot/create-backend-abstraction-layer branch February 13, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants