How to Use avformat_write_header in FFmpeg C API
Writing container headers is a crucial step in muxing multimedia
streams using the FFmpeg C API. This article explains how to initialize
an output format context, configure output streams with valid codec
parameters, open the output I/O context, and successfully call
avformat_write_header to write the file header and
initialize the muxer.
1. Initialize the Output Format Context
Before writing headers, allocate the AVFormatContext for
the output container using
avformat_alloc_output_context2:
AVFormatContext *out_ctx = NULL;
int ret = avformat_alloc_output_context2(&out_ctx, NULL, NULL, "output.mp4");
if (!out_ctx || ret < 0) {
// Handle error
}2. Add and Configure Streams
Containers require knowledge of the elementary streams they
encapsulate. You must add at least one stream via
avformat_new_stream and populate its codecpar
(AVCodecParameters):
AVStream *out_stream = avformat_new_stream(out_ctx, NULL);
if (!out_stream) {
// Handle error
}
// Populate codec parameters from an existing decoder context or manually
ret = avcodec_parameters_from_context(out_stream->codecpar, codec_ctx);
if (ret < 0) {
// Handle error
}
// Alternatively, copy from an input stream during remuxing
// avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);Ensure out_stream->time_base is set appropriately for
the muxer.
3. Open the Output File
Unless the output format flag specifies AVFMT_NOFILE,
you must open the output target using avio_open2:
if (!(out_ctx->oformat->flags & AVFMT_NOFILE)) {
ret = avio_open(&out_ctx->pb, "output.mp4", AVIO_FLAG_WRITE);
if (ret < 0) {
// Handle I/O error
}
}4. Call
avformat_write_header
Once streams and I/O are prepared, call
avformat_write_header. You can pass a pointer to an
AVDictionary containing muxer-specific options, or
NULL if no custom options are required.
AVDictionary *muxer_opts = NULL;
av_dict_set(&muxer_opts, "movflags", "faststart", 0);
ret = avformat_write_header(out_ctx, &muxer_opts);
if (ret < 0) {
char err_buf[AV_ERROR_MAX_STRING_SIZE];
av_strerror(ret, err_buf, sizeof(err_buf));
fprintf(stderr, "Error writing header: %s\n", err_buf);
// Handle error and clean up
}
// Free any options that were not consumed by the muxer
av_dict_free(&muxer_opts);Return Values and Post-Processing
- Success:
avformat_write_headerreturns0orAVSTREAM_INIT_IN_WRITE_HEADER(1) on success. - Failure: A negative
AVERRORcode indicates failure. Always check the return value before proceeding to write packets withav_interleaved_write_frame. - Resource Management: Any options consumed by the
muxer are removed from the options dictionary. Always free the remaining
dictionary with
av_dict_free. - Finalization: Any successful call to
avformat_write_headermust eventually be paired withav_write_trailer(out_ctx)after all packets are written to finalize the container structure properly.