How to Initialize libavformat in C

Initializing libavformat within an external C program is the essential first step to access FFmpeg's powerful audio and video container demuxing and muxing capabilities. This article provides a straightforward guide covering the necessary headers, library linking, network subsystem startup, format context allocation, and standard cleanup procedures for modern FFmpeg versions.

1. Include the Necessary Headers

To use libavformat, you must include its primary header file along with other fundamental FFmpeg headers, such as libavcodec and libavutil, depending on your program's scope:

#include <libavformat/avformat.h>
#include <libavutil/avutil.h>

When compiling, ensure your compiler can find these headers and links to the required libraries (typically -lavformat -lavcodec -lavutil).

2. Note on Deprecated Initialization

In older versions of FFmpeg (prior to version 4.0), it was mandatory to call av_register_all() to register all available muxers, demuxers, and protocols. In modern FFmpeg, this function is completely deprecated and removed; registration happens automatically at runtime. You do not need to call any registration function to initialize local file formats.

3. Initialize Network Subsystems (Optional)

If your application reads or writes streams over network protocols (such as HTTP, RTMP, or RTSP), you must explicitly initialize the global network components before attempting to open any network streams:

if (avformat_network_init() < 0) {
    // Handle network initialization failure
    return -1;
}

4. Allocate the Format Context

The core data structure of libavformat is AVFormatContext, which holds the metadata, stream details, and I/O information for a media container. You can allocate an empty context manually:

AVFormatContext *format_ctx = avformat_alloc_context();
if (!format_ctx) {
    // Handle memory allocation failure
    return -1;
}

Alternatively, you can skip manual allocation if you are opening an existing media file, as avformat_open_input() will automatically allocate the context if passed a pointer initialized to NULL.

5. Open an Input Stream

To finalize the initialization of the format context with actual media data, call avformat_open_input():

AVFormatContext *format_ctx = NULL;
const char *url = "input.mp4"; // or an rtsp/http stream

int ret = avformat_open_input(&format_ctx, url, NULL, NULL);
if (ret < 0) {
    char err_buf[AV_ERROR_MAX_STRING_SIZE];
    av_strerror(ret, err_buf, sizeof(err_buf));
    fprintf(stderr, "Could not open source %s: %s\n", url, err_buf);
    return ret;
}

Once opened, you can populate the stream information by calling avformat_find_stream_info(format_ctx, NULL).

6. Cleanup and Deinitialization

When your program is done processing media, release the allocated resources to prevent memory leaks:

  • Close the format context and free its memory:

    avformat_close_input(&format_ctx);
  • If you called avformat_network_init(), shut down the network subsystem when exiting:

    avformat_network_deinit();