Allocate AVCodecContext for Video in FFmpeg C API
This guide demonstrates how to properly allocate, configure, and
initialize an AVCodecContext for decoding a video stream
using the modern FFmpeg C API. The process involves identifying the
video stream, finding the appropriate decoder, allocating the context
using avcodec_alloc_context3, copying parameters from
AVCodecParameters, and opening the codec with
avcodec_open2.
Step-by-Step Implementation
In modern FFmpeg (libavcodec 57 and newer), stream configuration
details are stored in an AVCodecParameters struct inside
the AVStream. You must allocate a new
AVCodecContext independently and copy the stream parameters
into it.
1. Locate the Video Stream and Decoder
First, identify the video stream index from your opened
AVFormatContext and locate the corresponding
AVCodec:
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
AVFormatContext *fmt_ctx = /* initialized AVFormatContext */;
const AVCodec *decoder = NULL;
// Find the best video stream and its decoder
int video_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (video_stream_idx < 0) {
// Handle error: No video stream found
return -1;
}
AVStream *video_stream = fmt_ctx->streams[video_stream_idx];2. Allocate the AVCodecContext
Allocate the context using avcodec_alloc_context3().
Passing the decoder pointer automatically sets default
values specific to that codec:
AVCodecContext *codec_ctx = avcodec_alloc_context3(decoder);
if (!codec_ctx) {
// Handle error: Out of memory
return -1;
}3. Copy Parameters to the Context
Initialize the newly created context with the codec parameters found
in the stream container using
avcodec_parameters_to_context():
if (avcodec_parameters_to_context(codec_ctx, video_stream->codecpar) < 0) {
// Handle error: Failed to copy parameters
avcodec_free_context(&codec_ctx);
return -1;
}4. Open the Codec
Initialize the decoding context to prepare it for receiving packets:
if (avcodec_open2(codec_ctx, decoder, NULL) < 0) {
// Handle error: Could not open codec
avcodec_free_context(&codec_ctx);
return -1;
}Complete Example
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
AVCodecContext* create_video_decoder_context(AVFormatContext *fmt_ctx) {
const AVCodec *decoder = NULL;
int stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (stream_idx < 0) {
return NULL;
}
AVCodecContext *codec_ctx = avcodec_alloc_context3(decoder);
if (!codec_ctx) {
return NULL;
}
if (avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[stream_idx]->codecpar) < 0) {
avcodec_free_context(&codec_ctx);
return NULL;
}
if (avcodec_open2(codec_ctx, decoder, NULL) < 0) {
avcodec_free_context(&codec_ctx);
return NULL;
}
return codec_ctx;
}Cleanup
When finished decoding, free the allocated context using
avcodec_free_context() to release memory and associated
resources:
avcodec_free_context(&codec_ctx);