Skip to content

Conversation

@Ericky14
Copy link

@Ericky14 Ericky14 commented Dec 13, 2025

Summary

Add support for animated wallpapers including GIF animations and video files (MP4, WebM, MKV, etc.) with hardware-accelerated decoding.

Features

  • GIF support: Full GIF animation with proper frame timing and infinite looping
  • Video support: Hardware-accelerated video playback via GStreamer
    • DMA-BUF zero-copy rendering (NVIDIA, AMD, Intel)
    • Runtime codec detection with automatic fallback to software decode
    • Smart decoder selection: demotes non-functional NVIDIA decoders on AMD-only systems
    • Fallback to wl_shm when DMA-BUF unavailable
  • Viewport GPU scaling: Native-resolution frames scaled by compositor, not CPU
  • 60 FPS cap: Prevents excessive resource usage

Architecture

  • New animated module behind animated feature flag (enabled by default)
  • AnimatedPlayer: Unified interface for GIF and video playback
  • VideoPlayer: GStreamer-based player with hardware decode detection
  • CodecSupport: Runtime detection of available hardware decoders
  • DMA-BUF integration via zwp_linux_dmabuf_v1 protocol

Codec Handling

  • Probes GStreamer registry at startup to detect available decoders
  • Tests NVIDIA decoders for actual functionality (CUDA availability)
  • Demotes broken decoders to Rank::NONE so decodebin selects working alternatives
  • VAAPI pipeline only selected when appropriate decoder exists for container format
  • Supports openh264dec for H.264 on systems without VAAPI H.264 (e.g., Fedora AMD)

Performance

  • GIF rendering: ~3ms per frame (viewport scaling)
  • Video: Zero-copy DMA-BUF path keeps frames in GPU memory
  • Render time compensation maintains accurate animation timing

Dependencies

  • GStreamer 1.20+ (runtime, for video playback)
  • gif crate (for GIF decoding)
  • Optional: gstreamer1-plugin-openh264 for H.264 software decode on AMD/Fedora
  • Optional: gst-cuda-dmabuf plugin for NVIDIA zero-copy

Testing

Tested with:

  • GIF animations (various frame rates and sizes)
  • MP4/WebM videos at 1080p and 4K
  • Multi-monitor setups with different resolutions
  • NVIDIA (NVDEC) and AMD (VAAPI) hardware decode
  • AMD systems with openh264 fallback (no VAAPI H.264)

Custom Plugin

To achieve DMA-BUF compatibility with NVIDIA, this plugin was developed: https://github.com/Ericky14/gst-cuda-dmabuf

Related Issues

#69
#24

Ericky Dos Santos added 10 commits December 13, 2025 13:01
- Add GStreamer-based video player with NVIDIA NVDEC, AMD/Intel VAAPI support
- Implement DMA-BUF zero-copy rendering via zwp_linux_dmabuf_v1 protocol
- Add frame queue for decoupled GStreamer → Wayland rendering
- Add automatic H.264/HEVC → VP9 conversion for AMD hardware decode
- Add viewport-based GPU scaling for proper Zoom/Fit/Stretch modes
- Add graceful shutdown handling (SIGTERM/SIGINT) to prevent compositor freezes
- Add rayon parallel pixel conversion for wl_shm fallback path
- Respect FilterMethod config for image scaling quality
Replace CPU-based per-frame scaling with viewport protocol GPU scaling:

- Write native-resolution GIF frame to wl_shm buffer (868x485 = 1.6MB)
- Use wp_viewport to GPU-scale to screen resolution (1920x1080)
- Remove scaled_frame_cache and scale_image() - no longer needed
- Add render time compensation to maintain accurate frame timing

Performance improvement: ~30ms → ~3ms per frame (10x faster)

Also fixes:
- GIF looping: advance() now always returns true for GIFs
- GIF default delay: 10cs (100ms) instead of 100cs (1s) for delay=0
- Suppress unused pts field warning with #[allow(dead_code)]
- Remove convert.rs module (video transcoding no longer needed)
- Add demote_broken_nvidia_decoders() to detect non-functional NVDEC
  decoders (e.g., when CUDA unavailable on AMD-only systems) and
  demote them to Rank::NONE so decodebin selects working alternatives
- Update VAAPI pipeline to check for specific decoders (H.264/H.265/
  VP9/AV1) based on container format before selecting pipeline
- Fix tests and remove unused exports/fields

This enables MP4 (H.264) playback on AMD systems via openh264dec
when VAAPI H.264 is unavailable (Fedora patent restrictions).
@mmstick
Copy link
Member

mmstick commented Dec 13, 2025

Can we support AVIF instead of GIF?

@Ericky14
Copy link
Author

Can we support AVIF instead of GIF?

Added AVIF support as well, should be able to load either static or animated one.
You can test by changing the background config file manually, I assume these extra supported files need to be explicitly added to the settings app right? Since it doesn't let the users select arbitrary files

@mmstick
Copy link
Member

mmstick commented Dec 14, 2025

Yes we will need to update cosmic-settings to support the file types and generate thumbnails. The cosmic-greeter also reads this config to render its background, but it is software rendered so it needs a static background.

@Ericky14
Copy link
Author

@mmstick Curious what you think about how it should be implemented in settings
I think it might be a good idea to add a dbus interface to cosmic-bg with a method to generate a preview file
That way we can utilize the code written here to generate previews of any file type supported with a lower resolution so its optimized for the thumbnail, and in cosmic-settings we can just load from that file

@mmstick
Copy link
Member

mmstick commented Dec 15, 2025

The code for generating thumbnails is already there in cosmic-settings for the wallpaper page. You can add to it there.

@mmstick mmstick requested review from a team December 16, 2025 13:33
@Ericky14 Ericky14 requested a review from mmstick December 17, 2025 05:24
mmstick
mmstick previously approved these changes Dec 17, 2025
Copy link
Member

@jacobgkau jacobgkau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This failed to build on the build server, and is also failing locally.

Output:
just build-vendored
cargo build --release --frozen --offline
warning: both `/home/jacob/Work/cosmic-bg/.cargo/config` and `/home/jacob/Work/cosmic-bg/.cargo/config.toml` exist. Using `/home/jacob/Work/cosmic-bg/.cargo/config`
   Compiling proc-macro2 v1.0.101
   Compiling unicode-ident v1.0.18
   Compiling pkg-config v0.3.32
   Compiling cfg-if v1.0.3
   Compiling libc v0.2.175
   Compiling once_cell v1.21.3
   Compiling serde_core v1.0.228
   Compiling serde v1.0.228
   Compiling log v0.4.27
   Compiling winnow v0.7.13
   Compiling toml_datetime v0.7.3
   Compiling target-lexicon v0.13.3
   Compiling serde_spanned v1.0.3
   Compiling smallvec v1.15.1
   Compiling heck v0.5.0
   Compiling version-compare v0.2.0
   Compiling pin-project-lite v0.2.16
   Compiling rustix v1.0.8
   Compiling linux-raw-sys v0.9.4
   Compiling shlex v1.3.0
   Compiling find-msvc-tools v0.1.5
   Compiling slab v0.4.11
   Compiling autocfg v1.5.0
   Compiling libloading v0.8.8
   Compiling memchr v2.7.5
   Compiling cc v1.2.49
   Compiling scoped-tls v1.0.1
   Compiling downcast-rs v1.2.1
   Compiling wayland-client v0.31.11
   Compiling tracing-core v0.1.34
   Compiling either v1.15.0
   Compiling rustix v0.38.44
   Compiling crossbeam-utils v0.8.21
   Compiling linux-raw-sys v0.4.15
   Compiling thiserror v1.0.69
   Compiling rayon-core v1.13.0
   Compiling futures-sink v0.3.31
   Compiling futures-core v0.3.31
   Compiling dlib v0.5.2
   Compiling zerocopy v0.8.26
   Compiling futures-channel v0.3.31
   Compiling xcursor v0.3.10
   Compiling num-traits v0.2.19
   Compiling cursor-icon v1.2.0
   Compiling wayland-sys v0.31.7
   Compiling quick-xml v0.37.5
   Compiling pin-utils v0.1.0
   Compiling futures-task v0.3.31
   Compiling static_assertions v1.1.0
   Compiling futures-io v0.3.31
   Compiling siphasher v1.0.1
   Compiling smithay-client-toolkit v0.19.2
   Compiling rand_core v0.6.4
   Compiling cfg_aliases v0.2.1
   Compiling version_check v0.9.5
   Compiling hashbrown v0.16.1
   Compiling simd-adler32 v0.3.7
   Compiling equivalent v1.0.2
   Compiling phf_shared v0.11.3
   Compiling adler2 v2.0.1
   Compiling rand v0.8.5
   Compiling getrandom v0.3.3
   Compiling bytes v1.10.1
   Compiling cfg-expr v0.20.4
   Compiling raw-window-handle v0.6.2
   Compiling miniz_oxide v0.8.9
   Compiling crc32fast v1.5.0
   Compiling thiserror v2.0.16
   Compiling ahash v0.8.12
   Compiling nix v0.30.1
   Compiling quote v1.0.40
   Compiling crossbeam-epoch v0.9.18
   Compiling x11rb-protocol v0.13.2
   Compiling byte-slice-cast v1.2.3
   Compiling pastey v0.2.0
   Compiling palette v0.7.6
   Compiling syn v2.0.106
   Compiling by_address v1.2.1
   Compiling num-integer v0.1.46
   Compiling crossbeam-deque v0.8.6
   Compiling approx v0.5.1
   Compiling flate2 v1.1.2
   Compiling fdeflate v0.3.7
   Compiling kstring v2.0.2
   Compiling itertools v0.14.0
   Compiling bitreader v0.3.11
   Compiling lazy_static v1.5.0
   Compiling indexmap v2.12.1
   Compiling byteorder v1.5.0
   Compiling ident_case v1.0.1
   Compiling zune-core v0.4.12
   Compiling wayland-scanner v0.31.7
   Compiling toml_parser v1.0.4
   Compiling num-bigint v0.4.6
   Compiling option-operations v0.6.1
   Compiling muldiv v1.0.1
   Compiling bitflags v1.3.2
   Compiling phf_generator v0.11.3
   Compiling fnv v1.0.7
   Compiling quick-error v2.0.1
   Compiling byteorder-lite v0.1.0
   Compiling fast-srgb8 v1.0.0
   Compiling strsim v0.11.1
   Compiling zune-jpeg v0.4.20
   Compiling png v0.17.16
   Compiling sharded-slab v0.1.7
   Compiling tracing-log v0.2.0
   Compiling thread_local v1.1.9
   Compiling glam v0.25.0
   Compiling smol_str v0.2.2
   Compiling toml v0.9.8
   Compiling toml_edit v0.23.7
   Compiling image-webp v0.2.4
   Compiling libdav1d-sys v0.7.1+libdav1d.1.4.3
   Compiling wayland-backend v0.3.11
   Compiling fastrand v2.3.0
   Compiling object v0.36.7
   Compiling alloc-no-stdlib v2.0.4
   Compiling nu-ansi-term v0.50.1
   Compiling rustc-hash v2.1.1
   Compiling owo-colors v4.2.2
   Compiling system-deps v7.0.7
   Compiling web-time v1.1.0
   Compiling option-ext v0.2.0
   Compiling same-file v1.0.6
   Compiling alloc-stdlib v0.2.2
   Compiling cmake v0.1.56
   Compiling eyre v0.6.12
   Compiling walkdir v2.5.0
   Compiling gimli v0.31.1
   Compiling rayon v1.11.0
   Compiling base64 v0.22.1
   Compiling hashbrown v0.13.2
   Compiling color-spantrace v0.3.0
   Compiling atomic_refcell v0.1.13
   Compiling memmap2 v0.9.8
   Compiling inotify-sys v0.1.5
   Compiling proc-macro-crate v3.4.0
   Compiling tracing-subscriber v0.3.20
   Compiling mio v1.0.4
   Compiling num-rational v0.4.2
   Compiling dirs-sys v0.5.0
   Compiling notify-types v2.0.0
   Compiling rand_core v0.9.3
   Compiling libavif-sys v0.17.0+libavif.1.0.4
   Compiling fallible_collections v0.4.9
   Compiling dirs v6.0.0
   Compiling ppv-lite86 v0.2.21
   Compiling brotli-decompressor v5.0.0
   Compiling nix v0.29.0
   Compiling glib-sys v0.21.5
   Compiling gobject-sys v0.21.5
   Compiling gstreamer-sys v0.24.4
   Compiling gio-sys v0.21.5
   Compiling dav1d-sys v0.8.3
   Compiling gstreamer-base-sys v0.24.4
   Compiling mp4parse v0.17.0
   Compiling gstreamer-video-sys v0.24.4
   Compiling gstreamer-allocators-sys v0.24.4
   Compiling gstreamer-app-sys v0.24.4
   Compiling smithay-client-toolkit v0.20.0
   Compiling litrs v0.4.2
error: failed to run custom build command for `dav1d-sys v0.8.3`

Caused by:
  process didn't exit successfully: `/home/jacob/Work/cosmic-bg/target/release/build/dav1d-sys-56447bdbc5ff376d/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=/home/jacob/Work/cosmic-bg/vendor/dav1d-sys/Cargo.toml
  cargo:rerun-if-env-changed=DAV1D_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

  --- stderr

  thread 'main' panicked at /home/jacob/Work/cosmic-bg/vendor/dav1d-sys/build.rs:82:10:
  called `Result::unwrap()` on an `Err` value: PkgConfig(
  pkg-config exited with status code 1
  > PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags dav1d 'dav1d >= 1.3.0'

  The system library `dav1d` required by crate `dav1d-sys` was not found.
  The file `dav1d.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.
  The PKG_CONFIG_PATH environment variable is not set.

  HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `dav1d.pc`.
  )
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
warning: [email protected]:
error: failed to run custom build command for `gstreamer-allocators-sys v0.24.4`

Caused by:
  process didn't exit successfully: `/home/jacob/Work/cosmic-bg/target/release/build/gstreamer-allocators-sys-fedac2af41d524e4/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=/home/jacob/Work/cosmic-bg/vendor/gstreamer-allocators-sys/Cargo.toml
  cargo:rerun-if-env-changed=GSTREAMER_ALLOCATORS_1.0_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:warning=
  pkg-config exited with status code 1
  > PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags gstreamer-allocators-1.0 'gstreamer-allocators-1.0 >= 1.14'

  The system library `gstreamer-allocators-1.0` required by crate `gstreamer-allocators-sys` was not found.
  The file `gstreamer-allocators-1.0.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.
  The PKG_CONFIG_PATH environment variable is not set.

  HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `gstreamer-allocators-1.0.pc`.

warning: [email protected]:
error: failed to run custom build command for `gstreamer-video-sys v0.24.4`

Caused by:
  process didn't exit successfully: `/home/jacob/Work/cosmic-bg/target/release/build/gstreamer-video-sys-2d3daa7a7af5faf1/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=/home/jacob/Work/cosmic-bg/vendor/gstreamer-video-sys/Cargo.toml
  cargo:rerun-if-env-changed=GSTREAMER_VIDEO_1.0_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:warning=
  pkg-config exited with status code 1
  > PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags gstreamer-video-1.0 'gstreamer-video-1.0 >= 1.14'

  The system library `gstreamer-video-1.0` required by crate `gstreamer-video-sys` was not found.
  The file `gstreamer-video-1.0.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.
  The PKG_CONFIG_PATH environment variable is not set.

  HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `gstreamer-video-1.0.pc`.

warning: [email protected]:
error: failed to run custom build command for `gstreamer-base-sys v0.24.4`

Caused by:
  process didn't exit successfully: `/home/jacob/Work/cosmic-bg/target/release/build/gstreamer-base-sys-518ecd0f1ee52b66/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=/home/jacob/Work/cosmic-bg/vendor/gstreamer-base-sys/Cargo.toml
  cargo:rerun-if-env-changed=GSTREAMER_BASE_1.0_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:warning=
  pkg-config exited with status code 1
  > PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags gstreamer-base-1.0 'gstreamer-base-1.0 >= 1.24'

  The system library `gstreamer-base-1.0` required by crate `gstreamer-base-sys` was not found.
  The file `gstreamer-base-1.0.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.
  The PKG_CONFIG_PATH environment variable is not set.

  HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `gstreamer-base-1.0.pc`.

warning: [email protected]:
error: failed to run custom build command for `gstreamer-sys v0.24.4`

Caused by:
  process didn't exit successfully: `/home/jacob/Work/cosmic-bg/target/release/build/gstreamer-sys-b26cfb6787ab6871/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=/home/jacob/Work/cosmic-bg/vendor/gstreamer-sys/Cargo.toml
  cargo:rerun-if-env-changed=GSTREAMER_1.0_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:warning=
  pkg-config exited with status code 1
  > PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags gstreamer-1.0 'gstreamer-1.0 >= 1.24'

  The system library `gstreamer-1.0` required by crate `gstreamer-sys` was not found.
  The file `gstreamer-1.0.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.
  The PKG_CONFIG_PATH environment variable is not set.

  HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `gstreamer-1.0.pc`.

error: Recipe `build-debug` failed on line 45 with exit code 101
make[1]: *** [debian/rules:23: override_dh_auto_build] Error 101
make[1]: Leaving directory '/home/jacob/Work/cosmic-bg'
make: *** [debian/rules:8: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2

Looks like a new package likely needs to be added to the build-depends in debian/control?

@Ericky14
Copy link
Author

Ericky14 commented Dec 20, 2025

@jacobgkau I was trying to test this on PopOS directly, first issue I see is that you guys aren't using gstreamer 1.26, is there an easy way to update that dependency? gstreamer 1.24 doesn't have as good support for zero copy GPU pipelines (vapostproc doesn't export DMA-BUF)

I usually use Fedora 42, works great with the updated gstreamer packages.
On 1.24 its working with videos, but has high CPU usage since we need to use CPU

@jackpot51
Copy link
Member

@Ericky14 can you disclose if you have used an LLM to assist with making these changes, and if so, which one?

@Ericky14
Copy link
Author

Ericky14 commented Dec 31, 2025

@Ericky14 can you disclose if you have used an LLM to assist with making these changes, and if so, which one?

Yes, I use github copilot with claude opus 4.5, I found it to generate the best results
It's been helpful to learn about this ecosystem since I am relatively new to it

Even with an LLM, by no means was this easy
It took many days, LLMs aren't amazing with lower level programming

Copy link
Member

@jackpot51 jackpot51 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ericky14 The reason I ask about LLM assistance, is that this PR has a very large amount of very verbose code. The parts I read over had clear mistakes, such as trying to use the extension of the file to identify the codecs that should be used. Simply put, the current code quality is not something I would accept into a COSMIC project.

To put this in perspective, cosmic-player currently has 2,337 lines of Rust code. It uses iced_video_player which has 1,332 lines of Rust code. Just like this PR, gstreamer is used. However, this PR adds 5,428 lines, the majority of which is new Rust code. This adds considerable maintenance burden to this project which is not desired, and it is extremely important that any added code is well understood not only by the person submitting it, but also by the people reviewing and eventually maintaining it.

In its current state, I cannot accept this change. I'd like to see considerable cleanup, and also an attempt to use other iced and COSMIC projects to reduce the amount of new code. I would also like to see any contributor have complete understanding of their contributions, for the purpose of future maintenance.

I would not recommend any engineering or QA review of this change until these requirements are met.

@Ericky14
Copy link
Author

Ericky14 commented Jan 1, 2026

@jackpot51 I didn't know about iced_video_player, I'll take a look at that one.

Apologies for the code quality 😅
Although I wonder how iced_video_player can have optimal performance with less lines of code, I'll explore how performant it is.

Also just learned about using iced_layershell yesterday on a separate project. I'll try to do something cleaner, thanks for the constructive feedback.

@Ericky14
Copy link
Author

Ericky14 commented Jan 1, 2026

@jackpot51 Upon investigation, iced_video_player does nothing to optimize videos using GPU, and the code quality isn't great either..

I explored using iced_layershell with iced_video_player, first it was using too much CPU because it uses playbin and selects the software decoder
I tried modifying the pipeline to use

            "filesrc location=\"{}\" ! qtdemux ! h264parse ! nvh264dec ! \
            video/x-raw(memory:CUDAMemory),format=NV12 ! cudadownload ! \
            video/x-raw,format=NV12 ! appsink name=iced_video drop=true sync=true",

This still uses too much CPU, probably because wgpu does not support dmabuf importing and appsink requires CPU roundtrip. Relevant issue: gfx-rs/wgpu#2320
Screenshot_2026-01-01_12-08-22

Current performance using the code I wrote:
Screenshot_2026-01-01_11-35-09

I am testing on my desktop with 2 monitors connected, and a 4k video.

If you'd like to keep this PR I can refactor it however you want if you have suggestions, or move the video logic to another library. Let me know.
Doesn't seem possible to achieve same performance with iced.

Copy link
Member

@mmstick mmstick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't recommend ugly codecs because this will cause legal issues.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debian packages should not add third party PPAs to the system.

gstreamer1.0-plugins-bad,
Recommends:
gstreamer1.0-plugins-ugly,
gstreamer1.0-libav,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the libav and ugly packages contain codecs which are illegal for us to distribute.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can switch to openh264 and do some testing to see if it works well still.
But waiting on @jackpot51 before I spend any more of my time on this, he didn't sound like he wants this addition in cosmic-bg.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the animated image support should be packaged as its own separate crate that is shareable across apps that need the same functionality. And image/video detection would be better done based on media content instead of the extension. If something can be upstreamed to the gstreamer maintainers, it should. Likewise if possible it would be a good idea to contribute iced-specific integrations to iced-player.

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.

4 participants