Phase 2: Animation & Video Support
Goal
Add support for animated GIFs and video wallpapers with efficient frame rendering.
Tasks
2.1 Animated GIF Support
- Parse GIF files with frame-by-frame access
- Extract frame delays from GIF metadata
- Handle GIF disposal methods (replace, combine, etc.)
- Implement frame timing with proper delays
2.2 Double Buffering
- Create front and back buffer pixmaps
- Render to back buffer while displaying front
- Swap buffers atomically
- Minimize visual tearing
2.3 Animation Event Loop
- Timer-based frame advancement
- Adaptive frame skipping under load
- Max 60fps cap to prevent excessive CPU usage
- Pause/resume animation state
2.4 Video Decoding (Optional Feature)
- Integrate ffmpeg-next for video decoding
- Decode video frames to RGBA
- Handle common codecs (H.264, VP9, AV1)
- Support MP4 and WebM containers
2.5 Frame Pre-rendering Buffer
- Ring buffer of ~30 pre-decoded frames
- Background thread for frame decoding
- Producer-consumer pattern with channels
- Memory-efficient frame recycling
2.6 Animated WebP/APNG
- Detect animated WebP files
- Parse APNG frame structure
- Unified animation interface for all formats
Deliverables
garbg set ~/animation.gifplays animated GIFgarbg set ~/video.mp4plays video as wallpaper (with --features video)- Smooth playback at correct frame rates
- Minimal CPU usage during playback
Technical Notes
GIF Frame Timing
// GIF delays are in centiseconds (1/100th second)
let delay_ms = frame.delay * 10;
// Some GIFs have 0 delay, default to ~100ms
let delay_ms = if delay_ms == 0 { 100 } else { delay_ms };
Double Buffer Swap
// Render to back buffer
put_image(back_buffer, frame_data);
// Swap pointers
std::mem::swap(&mut front_buffer, &mut back_buffer);
// Set root to new front buffer
set_root_pixmap(front_buffer);
Video Pipeline
MP4/WebM File
|
v
[FFmpeg Demuxer]
|
v
[Video Decoder] --> Frame Queue (30 frames)
| |
v v
[Scaler/Converter] [Render Thread]
| |
v v
BGRA Data X11 PutImage
Files Modified/Created
/garbg/garbg/src/media/gif.rs- GIF decoder/garbg/garbg/src/media/video.rs- Video decoder (optional)/garbg/garbg/src/media/animation.rs- Animation frame management/garbg/garbg/src/x11/animation.rs- Double buffering/garbg/garbg/src/daemon/animation_loop.rs- Frame timing loop
View source
| 1 | # Phase 2: Animation & Video Support |
| 2 | |
| 3 | ## Goal |
| 4 | Add support for animated GIFs and video wallpapers with efficient frame rendering. |
| 5 | |
| 6 | ## Tasks |
| 7 | |
| 8 | ### 2.1 Animated GIF Support |
| 9 | - [ ] Parse GIF files with frame-by-frame access |
| 10 | - [ ] Extract frame delays from GIF metadata |
| 11 | - [ ] Handle GIF disposal methods (replace, combine, etc.) |
| 12 | - [ ] Implement frame timing with proper delays |
| 13 | |
| 14 | ### 2.2 Double Buffering |
| 15 | - [ ] Create front and back buffer pixmaps |
| 16 | - [ ] Render to back buffer while displaying front |
| 17 | - [ ] Swap buffers atomically |
| 18 | - [ ] Minimize visual tearing |
| 19 | |
| 20 | ### 2.3 Animation Event Loop |
| 21 | - [ ] Timer-based frame advancement |
| 22 | - [ ] Adaptive frame skipping under load |
| 23 | - [ ] Max 60fps cap to prevent excessive CPU usage |
| 24 | - [ ] Pause/resume animation state |
| 25 | |
| 26 | ### 2.4 Video Decoding (Optional Feature) |
| 27 | - [ ] Integrate ffmpeg-next for video decoding |
| 28 | - [ ] Decode video frames to RGBA |
| 29 | - [ ] Handle common codecs (H.264, VP9, AV1) |
| 30 | - [ ] Support MP4 and WebM containers |
| 31 | |
| 32 | ### 2.5 Frame Pre-rendering Buffer |
| 33 | - [ ] Ring buffer of ~30 pre-decoded frames |
| 34 | - [ ] Background thread for frame decoding |
| 35 | - [ ] Producer-consumer pattern with channels |
| 36 | - [ ] Memory-efficient frame recycling |
| 37 | |
| 38 | ### 2.6 Animated WebP/APNG |
| 39 | - [ ] Detect animated WebP files |
| 40 | - [ ] Parse APNG frame structure |
| 41 | - [ ] Unified animation interface for all formats |
| 42 | |
| 43 | ## Deliverables |
| 44 | - `garbg set ~/animation.gif` plays animated GIF |
| 45 | - `garbg set ~/video.mp4` plays video as wallpaper (with --features video) |
| 46 | - Smooth playback at correct frame rates |
| 47 | - Minimal CPU usage during playback |
| 48 | |
| 49 | ## Technical Notes |
| 50 | |
| 51 | ### GIF Frame Timing |
| 52 | ```rust |
| 53 | // GIF delays are in centiseconds (1/100th second) |
| 54 | let delay_ms = frame.delay * 10; |
| 55 | // Some GIFs have 0 delay, default to ~100ms |
| 56 | let delay_ms = if delay_ms == 0 { 100 } else { delay_ms }; |
| 57 | ``` |
| 58 | |
| 59 | ### Double Buffer Swap |
| 60 | ```rust |
| 61 | // Render to back buffer |
| 62 | put_image(back_buffer, frame_data); |
| 63 | // Swap pointers |
| 64 | std::mem::swap(&mut front_buffer, &mut back_buffer); |
| 65 | // Set root to new front buffer |
| 66 | set_root_pixmap(front_buffer); |
| 67 | ``` |
| 68 | |
| 69 | ### Video Pipeline |
| 70 | ``` |
| 71 | MP4/WebM File |
| 72 | | |
| 73 | v |
| 74 | [FFmpeg Demuxer] |
| 75 | | |
| 76 | v |
| 77 | [Video Decoder] --> Frame Queue (30 frames) |
| 78 | | | |
| 79 | v v |
| 80 | [Scaler/Converter] [Render Thread] |
| 81 | | | |
| 82 | v v |
| 83 | BGRA Data X11 PutImage |
| 84 | ``` |
| 85 | |
| 86 | ## Files Modified/Created |
| 87 | - `/garbg/garbg/src/media/gif.rs` - GIF decoder |
| 88 | - `/garbg/garbg/src/media/video.rs` - Video decoder (optional) |
| 89 | - `/garbg/garbg/src/media/animation.rs` - Animation frame management |
| 90 | - `/garbg/garbg/src/x11/animation.rs` - Double buffering |
| 91 | - `/garbg/garbg/src/daemon/animation_loop.rs` - Frame timing loop |