How to Use av_interleaved_write_frame in FFmpeg
This article explains how to write individual encoded media packets
to an output file container using FFmpeg’s
av_interleaved_write_frame function. You will learn the
step-by-step process of preparing your packets, managing stream
timestamps, and safely writing the data to ensure a correctly
multiplexed output file.
Understanding av_interleaved_write_frame
The av_interleaved_write_frame function is used to write
media packets (audio, video, or subtitles) into an output container.
Unlike av_write_frame, which writes packets immediately to
the file, av_interleaved_write_frame buffers packets
internally to ensure they are written in ascending order of their
Decoding Timestamp (DTS). This interleaving is critical for standard
media players to stream and play back the file without synchronization
issues.
Step 1: Prepare the Output Packet
Before writing, you must obtain an encoded packet
(AVPacket) from your encoder using
avcodec_receive_packet. Once you have a populated packet,
assign it to the correct stream in your output format context:
// pkt is the AVPacket received from the encoder
// stream_index corresponds to the index of the stream in the output AVFormatContext
pkt->stream_index = out_stream->index;Step 2: Rescale the Timestamps
Timestamps in FFmpeg are relative to the timebase of the codec or stream. Encoder timebases often differ from container stream timebases. You must rescale the packet’s Presentation Timestamp (PTS), Decoding Timestamp (DTS), and duration to the output stream’s timebase before writing.
FFmpeg provides a utility function to handle this conversion:
av_packet_rescale_ts(pkt, codec_ctx->time_base, out_stream->time_base);Step 3: Write the Packet
Call av_interleaved_write_frame by passing the output
format context and the prepared packet.
int ret = av_interleaved_write_frame(out_format_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error while writing interleaved frame: %s\n", av_err2str(ret));
// Handle error (e.g., free packet and exit)
}Memory Management Note
When you call av_interleaved_write_frame, FFmpeg takes
ownership of the packet passed to it. The function internally buffers
the packet and will automatically call av_packet_unref to
free its payload once it is written to disk. You do not need to manually
unreference the packet after a successful call, but you should prepare a
clean packet for the next encoding iteration.
Step 4: Flush the Interleave Buffer
At the end of the writing process (when you reach EOF of your input
streams), some packets may still reside in the interleaver’s internal
buffer. To flush these remaining packets and finalize the file
structure, pass NULL as the packet parameter:
// Flush the interleaver
av_interleaved_write_frame(out_format_ctx, NULL);
// Write the trailer to finalize the output file structure
av_write_trailer(out_format_ctx);