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);