Comparing a standard CPU video pipeline with a zero-copy GPU pipeline, featuring the VLC and Vulkan logos
Ongoing Started May 2026 7 entries

GSoC 2026 with VideoLAN: teaching VLC to show GPU video without the copy

Engineering a zero-copy Vulkan interop pipeline for VLC's libplacebo renderer

I'm spending the summer with VideoLAN fixing a bottleneck in VLC. Right now, even when a video is decoded on the GPU, VLC copies the frames down to system memory and back up again just to draw them on the libplacebo video output through Vulkan. My project is to build a zero-copy hardware interop.

  1. My GSoC 2026 Project Overview
    Part 15 min read

    My GSoC 2026 Project Overview

    Starting Google Summer of Code 2026 with VideoLAN, teaching VLC to draw GPU-decoded frames without copying them through the CPU first. The series opener: who I am and the round-trip I'm here to delete.

    Read this part
  2. Week 1: first patch written
    Part 23 min read

    Week 1: first patch written

    Week 1 of my GSoC with VideoLAN: a first patch that changes nothing on purpose, an assumption that fell apart once I read the source.

    Read this part
  3. Week 2: NVDEC the easy way first
    Part 34 min read

    Week 2: NVDEC the easy way first

    Before porting NVDEC to Vulkan, I got it playing zero-copy through OpenGL first, so I have a known-good reference to compare against. Then a long time reading my mentor's branch.

    Read this part
  4. Week 3: first light on the Vulkan path
    Part 48 min read

    Week 3: first light on the Vulkan path

    An NVDEC frame decoded on the GPU, imported into Vulkan with no CPU copy, and drawn by libplacebo. It works, the 4K file plays with correct colors. Then I turned on Vulkan's validation layer and it flagged the code as illegal, the same code NVIDIA had been drawing.

    Read this part
  5. Week 4: the green noise that proved the obvious fix was wrong
    Part 53 min read

    Week 4: the green noise that proved the obvious fix was wrong

    Last week's validation error said my image can't be both disjoint and dedicated at once. The obvious fix was to drop the dedicated part, so I did, and the color fell apart into green noise across the sky and the water.

    Read this part
  6. Week 5: syncing the NVDEC copy and the render
    Part 65 min read

    Week 5: syncing the NVDEC copy and the render

    I had to make CUDA's copy and libplacebo's render take turns over one image, using a single timeline counter shared across both APIs with no CPU copy.

    Read this part
  7. Week 6: writing the frame sync into code
    Part 72 min read

    Week 6: writing the frame sync into code

    Last week I designed the handshake that keeps CUDA and the renderer from touching the same image at once. This week I wrote it, then spent most of my time making sure it was actually correct.

    Read this part
More to come - this journey is still in progress
© 2026 Ahmed Sobhy. All rights reserved.