Allocate AVCodecContext for Video Stream in FFmpeg

This article provides a direct, step-by-step guide on how to properly allocate and initialize a decoding context (AVCodecContext) for a video stream using the FFmpeg C API. You will learn how to locate the correct decoder, allocate the memory for the context, populate it with stream parameters, and open the codec for decoding.

Step 1: Find the Decoder

Before allocating the context, you must identify the appropriate decoder for the video stream. This is done by extracting the codec ID from the stream’s parameters and passing it to avcodec_find_decoder.

// Assuming 'format_context' is your opened AVFormatContext* 
// and 'video_stream_index' is the index of your video stream.
AVStream* stream = format_context->streams[video_stream_index];

const AVCodec* codec = avcodec_find_decoder(stream->codecpar->codec_id);
if (!codec) {
    fprintf(stderr, "Unsupported codec!\n");
    return -1;
}

Step 2: Allocate the Codec Context

Once you have the AVCodec pointer, use avcodec_alloc_context3 to allocate the AVCodecContext structure. Passing the codec pointer ensures the context is initialized with defaults specific to that codec.

AVCodecContext* codec_context = avcodec_alloc_context3(codec);
if (!codec_context) {
    fprintf(stderr, "Could not allocate video codec context\n");
    return -1;
}

Step 3: Copy Stream Parameters to the Context

An allocated context is empty of stream-specific configurations (like resolution, framerate, or pixel format). Use avcodec_parameters_to_context to copy these settings from the container’s stream parameters to your new decoding context.

if (avcodec_parameters_to_context(codec_context, stream->codecpar) < 0) {
    fprintf(stderr, "Failed to copy codec parameters to decoder context\n");
    avcodec_free_context(&codec_context);
    return -1;
}

Step 4: Open the Codec Context

Finally, initialize the codec context by calling avcodec_open2. This prepares the decoder to begin accepting packets and outputting raw video frames.

AVDictionary* options = NULL; // Pass custom parser options here if needed
if (avcodec_open2(codec_context, codec, &options) < 0) {
    fprintf(stderr, "Could not open codec\n");
    avcodec_free_context(&codec_context);
    return -1;
}

Cleaning Up

Once you are finished decoding the video stream, prevent memory leaks by freeing the context using avcodec_free_context.

avcodec_free_context(&codec_context);