Today was my sixth day and the start of my second week at the Recurse Center as a participant in this year’s Summer 2 batch!

Writing

I had some really good discussions this morning about how to make the most of our time in-batch. A few of us1 also discussed how to capture a large volume of ideas and new discoveries so we don’t forget them. A common thread seems to be that writing first for oneself and then for an audience is a good way to first get ideas onto the page and then structure thoughts and solidify one’s understanding of a topic.

Lately, I’ve been using Logseq as a tool to capture thoughts and ideas throughout the day. I don’t worry too much about structuring them as I capture things - I just create a new bullet point whenever I want to add something. If I’m taking notes on a meeting or specific topic I’ll nest bullet points under that topic, but otherwise I don’t worry too much about where things go. This lack of pressure to provide any polish or structure up front has greatly increased the volume of ideas I write down, which has in turn made it easier to keep writing and share ideas on Zulip and on this blog. I’ve also given myself permission to make these daily blog posts as short or as long as they need to be. If at some point I only have one sentence to write about a given day, that would be OK.

Linking to a Rust library from C

Later in the day I spent some time pairing with Rhea on my project to link to a Rust library from ffmpeg.

With a few hacks, we were able to get ffmpeg to build and link against our toy Rust library today! At some point I plan to write up what was needed to make that work.

On second thought, in the spirit of capturing discoveries before they’re forgotten, here’s the gist of what we’ve done so far:

  • Created a new library crate (cargo new --lib ffout)
  • Added no-op stubs for some functions in src/lib.rs that I think we’ll need:
    • write_header
    • write_packet
    • write_trailer
  • Added the ffmpeg-sys-next crate to our dependencies in Cargo.toml
  • use‘d the necessary types in src/lib.rs to provide appropriate function signatures — namely:
    • use ffmpeg_sys_next::{AVFormatContext, AVPacket}
    • use std::os::raw::c_int;
  • Made the functions all pub extern "C" and marked them #[no_mangle] so the correct symbols get exported
  • Set crate-type in Cargo.toml to ["cdylib", "staticlib"] to build C-compatible dynamic and static libraries
  • Figured out that this only seems to work when building --release targets for some reason
  • Realized we needed to produce a header file for these libraries
  • Found cbindgen and added it to our build.rs to create a header file at target/release/ffout.h
  • Figured out how to configure cbindgen to produce C header files instead of C++ header files (cbindgen.toml)
  • Determined we’ll also want to produce a pkg-config file (libffout.pc)
  • Borrowed heavily from other patches to produce a changeset for ffmpeg itself to optionally build with support for our library
    • (Note: this part is almost certainly not correct yet, but it’s close enough to test basic linking at least)
  • Learned about cargo-c and its slightly more opinionated approach to building C ABI libraries like this
  • Decided to keep doing things by hand a bit more before adopting cargo-c
  • Added some code to build.rs to write a statically defined target/release/libffout.pc
  • Added a Makefile to “install” and “uninstall” our library from /usr/local for testing
  • Spent a good portion of the afternoon just making names and paths match up correctly
    • Fun fact I knew: linking C libaries by convention drops any leading lib prefix from the library name in the linker flags (e.g. -lffout to link against libffout.a)
    • Fact I had forgotten: by convention, header files also drop the lib portion of the library’s full name (e.g. libffout/ffout.h)
  • One last hack: since Homebrew doesn’t seem to link ffmpeg’s libraries or headers into /usr/local, we put the path of my local ffmpeg git checkout direclty into our libffout.pc configuration’s include flags so that ffmpeg could find its own headers which define the AVFormatContext and AVPacket structs our functions accept

In the end we were able to get our patched ffmpeg’s ./configure script to run without error, and make even worked!

My repos for work this are public on GitHub, but they’re not really in a tutorial or walkthrough state of cleanliness so I’m not linking directly to them here for now. If you’re curious about any of this though, feel free to poke around my GitHub profile and/or ping me on Hachyderm, Bluesky, Discord, or even Twitter or wherever else you can find me.

Media over QUIC (MoQ) and CDNs

After that I spent some time catching up with non-RC collaborators and other folks interested in MoQ and talked about things like what “CDN support” means for a protocol like this as compared to something like WebRTC.

Tomorrow, I’ll take the day off of RC to spend with family.


  1. Erika, Rachael, and Aditya