Migrating to Libav10

When in doubt about the proper way to replace old API usage, consult the doc/APIchanges file in the source directory and/or ask on the user IRC channel.

Removed APIs

API removed in Libav 9


They had been replaced by avformat_open_input.


It had been replaced with avformat_find_stream_info.

avcodec resampler

av_resample* and all related APIs have been dropped. Applications are supposed to use libavresample instead.

audio decoding API

The deprecated avcodec_decode_audio3() API function has been removed. avcodec_decode_audio4() must be used instead.

The old function decodes straight into a provided int16_t data buffer. This has some limitations, such as:

  • the buffer is allocated by the callers before decoding, but there is no way for the callers to know the required buffer size. This is problematic for codecs with highly variable frame sizes
  • planar (non-interleaved) formats cannot be supported
  • the decoder cannot return auxiliary information, such as timestamps, side data, etc.

The new function decodes into an AVFrame, which solves all of those problems. The most naive and straightforward conversion from the old code to the new code is:

  • before decoding starts, allocate an AVFrame with av_frame_alloc()

  • pass this frame to avcodec_decode_audio4()

  • memcpy(out_buf, frame->data[0], av_get_bytes_per_sample(avctx->sample_fmt) * avctx->channels * frame->nb_samples)

  • at the end of the decoding, use av_frame_free(&frame)

This will only work for interleaved sample formats, i.e. if av_sample_fmt_is_planar(avctx->sample_fmt) returns 0. For planar sample formats, you can either

  • modify your code to support planar sample formats;
  • use libavresample to convert to interleaved format

Audio and video encoding APIs

The deprecated avcodec_encode_audio() and avcodec_encode_video() functions have been removed. avcodec_encode_audio2() and avcodec_encode_video2() must be used instead.

The old audio and video functions take a plain short data buffer and an AVFrame, respectively, as input and encode into a plain uint8_t data buffer provided by the caller. This has a number of limitations, such as:

  • audio encoders can only support interleaved formats, not planar;
  • no auxiliary information, such as timestamps or side data, can be passed to audio encoders
  • the callers have to allocate the encoding buffer before encoding, without any way to know the size of the encoded data
  • no auxiliary information, such as timestamps or side data, can be received from the encoders

The new functions have the same signature and semantics for both audio and video, and solve all of those problems. They take an AVFrame as input and produce an AVPacket as output. The output packet can be allocated by the encoder, which ensures that the correct amount of space is provided. Since most current callers of the libavcodec encoding API then pass the encoded data to libavformat for muxing, the simplest way to migrate to the new API is

  • audio only (interleaved only):
    • before encoding starts, allocate an input AVFrame with av_frame_alloc() and set frame->format to your sample format, frame->sample_rate to the audio sampling rate, frame->channel_layout to the channel layout (use av_get_default_channel_layout() if you only know the channel count)

    • before each encode call, set frame->data[0] to your input data buffer, frame->linesize[0] to the buffer size, frame->nb_samples to the number of samples (usually equal to avctx->frame_size)

  • initialize an AVPacket, so that its data field is NULL and the size field is 0; this indicates to the encoder that it should allocate the buffer for the encoded data itself

  • pass this packet and your input frame the encoding function; the encoder will fill the packet with the encoded data, proper timestamps from the frame, and other information
  • this packet may be directly passed to av_interleaved_write_frame() for muxing (do not forget to set the stream index and rescale the timestamps to the stream timebase first)

  • if you do not pass the packet to libavformat, do not forget to free it with av_packet_unref()


Along with the previously mentioned audio encoding and decoding APIs, the AVCODEC_MAX_AUDIO_FRAME_SIZE macro was also removed. The reasons for that are:

  • In the old audio encoding API, the caller had to provide a buffer for encoded data, without having any way to know how large it had to be. AVCODEC_MAX_AUDIO_FRAME_SIZE was an arbitrarily chosen number that was considered to be large enough for all encoders, so the caller could safely use it as the buffer size. In the new audio encoding API, the output buffer should in most cases (unless the caller specifically requires otherwise, for some weird reason) be allocated by the encoder, which has a much better estimate of the required size. The new API does not specify any limit on the size of the encoded data.
  • Similarly, in the old audio decoding API the caller had to supply a buffer for the decoded data, without knowing the required size. In the new API, the buffer for the decoded data is allocated through the get_buffer() callback mechanism, same as for video, and again there is no specified limit on the decoded data size (and due to the introduction of planar audio and the existence of different sample formats, specifying a limit in bytes does not really make sense).

So in the context of the new APIs, AVCODEC_MAX_AUDIO_FRAME_SIZE is just an arbitrary number without any well-defined meaning, and this is why it was removed.

We have seen may callers simply replace this macro with the value 192000 it used to have. This solution is in the vast majority of cases a sub-optimal (or even outright wrong) one. The correct solutions for the majority of users would be:

  • For encoding, simply let libavcodec allocate the encoded data buffer, by setting data/size on the AVPacket to NULL/0.
  • For decoding, again let libavcodec allocate the decoded data buffer by not doing anything special (i.e. not overriding get_buffer2()).


This field was basically never used for its intended purpose, thus it was deprecated and removed. The callers should use avg_frame_rate instead.


Should be replaced with avformat_close_input(&context) (note that the pointer to the pointer to the context is passed to the function, so & must be applied to the parameter previously used for av_close_input_file()).

Changed functionality

Reference counted AVPackets

  • av_packet_ref and av_packet_unref replace the usage of av_dup_packet.

Macro namespace change

  • PIX_FMT_ flags become AV_PIX_FMT_FLAG_, now consistent with the rest of the pixel format API.

  • CODEC_ID_* and CodecID have been deprecated for a long time and this release removes it altogether. Please use AV_CODEC_ID_* and AVCodecID instead.


Consistent Frame Management

  • avcodec_alloc_frame had been deprecated in favour of av_frame_alloc.

  • avcodec_get_frame_defaults had been deprecated in favour of av_frame_unref.

  • avcodec_free_frame had been deprecated in favour of av_frame_free.

Code move


  • av_fast_malloc and av_fast_mallocz were moved to libavutil, use the header libavutil/mem.h.