How to Build a C App with FFmpeg libavcodec

This guide provides a straightforward walkthrough on creating, compiling, and running a standalone C program that links against FFmpeg's libavcodec library. You will learn the required system dependencies, examine a modern, minimal C example demonstrating codec initialization, and see the exact compilation command using pkg-config to ensure all library flags and header paths resolve correctly.


1. Install Required Development Libraries

Before compiling code against FFmpeg, you must install the development packages for libavcodec and its core dependency, libavutil.

On Debian/Ubuntu systems:

sudo apt update
sudo apt install build-essential pkg-config libavcodec-dev libavutil-dev

On Fedora/RHEL systems:

sudo dnf install gcc pkgconf-pkg-config ffmpeg-devel

On macOS (via Homebrew):

brew install ffmpeg pkg-config

2. Write the C Application

Create a file named codec_test.c. The following modern FFmpeg code searches for an H.264 decoder, initializes an AVCodecContext, opens the codec, and safely frees all allocated resources. Note that avcodec_register_all() is deprecated and omitted, as modern FFmpeg versions initialize codecs automatically.

#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>

int main(void) {
    // 1. Find the decoder by ID or name
    enum AVCodecID codec_id = AV_CODEC_ID_H264;
    const AVCodec *codec = avcodec_find_decoder(codec_id);
    if (!codec) {
        fprintf(stderr, "Codec not found: %s\n", avcodec_get_name(codec_id));
        return 1;
    }
    printf("Found decoder: %s (%s)\n", codec->name, codec->long_name);

    // 2. Allocate the codec context
    AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
    if (!codec_ctx) {
        fprintf(stderr, "Could not allocate video codec context\n");
        return 1;
    }

    // 3. Initialize/Open the codec context
    if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        avcodec_free_context(&codec_ctx);
        return 1;
    }
    printf("Successfully initialized %s codec context.\n", codec->name);

    // 4. Free the context and clean up
    avcodec_free_context(&codec_ctx);

    return 0;
}

FFmpeg components depend heavily on compiler optimization flags and system threading libraries. The most reliable way to compile your application is by querying pkg-config for the correct include paths (--cflags) and linker flags (--libs).

Run the following command in your terminal:

gcc codec_test.c -o codec_test $(pkg-config --cflags --libs libavcodec libavutil)
  • pkg-config --cflags libavcodec libavutil outputs the directory paths to the FFmpeg header files (e.g., -I/usr/include/x86_64-linux-gnu).
  • pkg-config --libs libavcodec libavutil outputs the appropriate link flags and dependencies (e.g., -lavcodec -lavutil).

4. Run the Binary

Execute the compiled executable:

./codec_test

If successful, the program output will confirm that the H.264 decoder was found and its context was successfully opened and closed without errors:

Found decoder: h264 (H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10)
Successfully initialized h264 codec context.