My GSoC 2026 Project Overview

My GSoC 2026 Project Overview

Jun 12, 20265 min read250 views

Hi, I'm Ahmed

I'm Ahmed Mohamed Sobhy, a Computer Engineering student at Cairo University and I like low-level systems code in C. This summer, I'm working on something a few billion devices actually run: Google Summer of Code 2026 with VideoLAN, working on VLC's video output, mentored by Thomas Guillem. I plan to write a weekly blog post, writing down my journey week by week, sharing all the details and progress I make. I hope by the end of this, I come out with a well-organized timeline for the whole journey and have a journal to write all my learnings throughout.

The project in one paragraph

VLC can already decode video on the GPU: NVIDIA has NVDEC, Intel and AMD have VA-API, Android has MediaCodec. But VLC's modern renderer, built on a library called libplacebo, only understands frames in CPU memory. So a hardware-decoded frame gets downloaded from the GPU to the CPU, then uploaded right back to the GPU to be drawn. Two trips across the bus, per frame, for pixels that never needed to move. My job is to delete that round-trip.

Wait, this isn't the project I applied for

The project I applied for is not the one I'm doing. I proposed something called Vulkan Video Filters: Tonemapping and Subtitles: adding HDR tonemapping and subtitle drawing to an experimental Vulkan output my mentor had written. I spent the weeks before the deadline living in that branch. I built it, got a tonemapping proof of concept working, and sent a stack of small fixes to VLC to learn my way around the codebase.

Right after I submitted, Thomas emailed with a team decision: VLC would do its Vulkan rendering through the existing work-in-progress libplacebo output, not the separate Vulkan output he had written. His branch stays useful as a reference for features the libplacebo path is still missing, but it is not the thing we build on anymore.

You would think that sinks a proposal built entirely on that branch. It didn't. The goal underneath was always the same, make VLC's Vulkan path do what its OpenGL path already does, so the work just moved onto the libplacebo output and refocused on the lower-level piece: hardware decoder interop, plus an external renderer mode.

I was glad it landed there. Interop was the part I had already been reading in the Vulkan branch, so I knew it best, and it is the lower-level work I enjoy most. The tonemapping from my original proposal is not really gone either: on the libplacebo output, libplacebo handles most of that on its own. And Niklas Haas, who wrote libplacebo, is helping on the project.

How VLC plays a video

VLC is built out of plugins it calls modules, and playback is a little assembly line of them:

File / Network Access Demux Decoder Filters (optional) Video output Screen stream frame A local file or network stream Reads raw bytes from the source Splits it into audio, video & subtitle tracks Decodes to raw pictures, on the CPU or GPU Optional: scale, deinterlace, crop, color tweaks Draws pictures to the display via a renderer What the viewer finally sees decoder device + video context (hardware only)
The VLC playback pipeline. My work is the handshake between the decoder and the video output.
Software picture

Actual pixels in CPU memory. Any renderer can read them. This is all VLC's libplacebo output understands today.

Hardware picture

The pixels live in GPU memory. VLC only passes around an opaque handle. The renderer can't read it without interop.

What is an "interop"?

Sharing GPU memory between two APIs that don't normally talk, here a hardware decoder and a Vulkan renderer, without copying it. The frame stays in the same video memory and the renderer just gets a new handle to it. Most of my summer is making that work, and making it safe, since two processors on the same memory have to agree on who reads when.

The gap I'm filling

The OpenGL vout solved this years ago with a family of modules called glinterop, one per decoder, that import GPU memory directly. The Vulkan/libplacebo output has no equivalent, so hardware frames take the wasteful CPU detour instead. I'm building that missing layer, vkinterop, following the pattern that already works.

Wait, what is libplacebo?

It's a GPU rendering library originally built for the mpv player, created by Niklas Haas. It handles the high-quality stuff: scaling, color management, HDR tone-mapping. In VLC it acts as a video output backend. VLC does the hard work of decoding the compressed file, then hands the raw frames to libplacebo, which uses your GPU to build the final picture before it reaches your display. Since he wrote it, having Niklas on the project means we can ask for more from the API if we hit a wall.

What I'm building

The work is two pieces:

  1. Hardware decoder interop: frames from NVDEC (first target), VA-API, and Android MediaCodec, handed to libplacebo as Vulkan images with zero copies, plus the synchronization that keeps decode and render from stepping on each other.
  2. An external renderer mode, so another application, say a game engine or OBS, can hand VLC its own Vulkan device and get video rendered straight into its world.

Follow along

New posts land roughly weekly: what I did, what went wrong, what I learned, including the embarrassing parts. All my code lands as merge requests on VideoLAN's GitLab, and I'll link them from each post so you can read the actual patches. I hope you enjoy the read.

Did you enjoy this article?

Share this article

Comments(4)

Leave a comment

O
OmarJun 17, 2026

Very nice, would love to stream some windows on this interop sometime

L
LoayJun 14, 2026

It looks like a very interesting and promising project! Please keep us updated

A
Ahmed AmrJun 13, 2026

It's so PEAK

H
HabibaJun 13, 2026

Nice read! I like how this is laid out and can't wait for the rest of the series.

ยฉ 2026 Ahmed Sobhy. All rights reserved.