Migrating to Libav12

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



The AVFilterPad struct is no longer public. Most of its fields were not intended to be public and so should not have been accessed by the callers. The two exceptions are name and type, which should now be accessed through avfilter_pad_get_name() and avfilter_pad_get_type() respectively.

Since the size of AVFilterPad is no longer public, the avfilter_pad_count() function is provided to get the number of filter inputs or outputs.


A bunch of struct members in libavfilter, storing the number of elements in an array, were called arrayname_count. This was inconsistent with the rest of Libav, where such fields are usually named nb_arrayname. To restore consistency, the old *_count fields were replaced with nb_*.


Originally, libavfilter used struct's called AVFilterBuffer and AVFilterBufferRef to store frame data and its properties. This largely mirrored another struct used in libavcodec -- AVFrame. To avoid having two structs doing essentially the same thing, AVFrame was moved from libavcodec to libavutil and is now used by both libavcodec and libavfilter. So all previous uses of AVFilterBufferRef are now replaced by AVFrame.



The request_channels AVCodecContext field has been replaced by request_channel_layout. This field was typically used to request decoder downmix to mono or stereo, so in new code one would instead of request_channels = 1 / 2 write request_channel_layout = AV_CHANNEL_LAYOUT_MONO / AV_CHANNEL_LAYOUT_STEREO.

AVPacket.destruct / AVPacket.priv

Those two fields were used to allow rudimentary custom memory management with AVPacket. However, AVPacket has now been changed to use reference-counted AVBuffers as the data backend , which also allow custom memory management. As a result, those two fields were no longer needed and were thus removed. For migrating your old code to use AVBuffer, see AVBuffer doxygen documentation, especially av_buffer_create().


Those three callbacks were the mechanism used by libavcodec decoders to allow the callers to do their own memory management. It was commonly used by the callers to implement reference counting of the decoded frames and so keep them around as long as needed (otherwise, the frames were only valid between two decode calls).

Since AVFrame has been switched to use the reference-counted AVBuffer API as the data backend, the situation has changed as follows:


This set of functions were a leftover from the move of AVFrame from lavcodec to lavuvutil. They were simply outdated, and badly interacting with the new memory refcouting capability. For example avcodec_free_frame() leaked, as that function does not free the data buffers, as it does not know how, since they might have been allocated with a custom get_buffer()).

As such, all these functions have been removed, and users should switch to av_frame_alloc(), av_frame_unref(), and av_frame_free() respectively.


This function and associated libavcodec module offered basic deinterlacing capabilities. However this feature does not belong to a encoder and decoder only library, and much better alternatives have been implemented in its place.

Users who need deinterlace capabilities are encouraged to use the yadiff filter from libavfilter.

thread_opaque and pkt

These fields were never part of the public API, and have been removed.


Pixel format compatibility names

All the prefixless PIX_FMT values from the AVPixelFormat enum have been removed. Users should update their code with the AV-prefixed version.

AVPixFmtDescriptor table

Having the table public is dangerous, since the caller has no way to know how large it actually was. It also prevents adding new fields to AVPixFmtDescriptor and AVComponentDescriptor without a major bump.

For these reasons, public access to this table has been removed, and its fields may be accessed exclusively using the av_pixdesc_* functions.


This function and the associated table has been removed from the public API. It hadn't been exposed at all in MSVC DLL builds, and by getting rid of it, we make the public API similar to all users.

The rationale is that public data symbols are problematic from a portability point of view: they behave differently than public functions in DLLs and require jumping through extra hoops, which we've chosen not to jump through -- the MSVC portability is quite tricky enough as it is without bothering with this aspect.

crypto context size variables

The old API where the plain size is exposed is not of much use - in most cases it is allocated dynamically anyway. If allocated e.g. on the stack via an uint8_t array, there's no guarantee that the struct's members are aligned properly (unless the array is overallocated and the opaque pointer within it manually aligned to some unspecified alignment).

The global variables that exported this values have been removed. Instead of providing a buffer of the previously reported size, users should simply use the appropriate alloc function (eg. av_md5_alloc()).


This header has been removed in favour of channel_layout.h.

lls functions



No API has been removed from this library.


SWS_CPU_CAPS defines

The public SWS_CPU_CAPS flags have been removed. They were unused and had no effect since the CPU capabilities auto-detection had been implemented.

Changed functionality


Export audio encoder padding

Currently, the amount of padding inserted at the beginning by some audio encoders, is exported through AVCodecContext.delay. However

Therefore, add a new field -- initial_padding and deprecate delay for encoding.

Export video decoder framerate

When decoding, this field holds the inverse of the framerate that can be written in the headers for some codecs. Using a field called time_base for this is very misleading, as there are no timestamps associated with it. Furthermore, this field is used for a very different purpose during encoding.

Add a new field, called framerate, to replace the use of time_base for decoding.

Enable side data-only packets

Encoders can output empty packets to deliver side-data information.


Context reintialization

The automatic context close/open for resampling compensation has been dropped: it added unnecessary complication for insignificant usability improvement. The user should know if they need resampling compensation before opening the context.



The size of the AVPixFmtDescriptor.flags field has been extended to uint64_t from uint8_t. This will allow offering new AV_PIX_FMT_FLAGS in the future.

AVComponentDescriptor bitpacking

The structure is no more bit packed, as it offered no practical benefits. All the fields are now simple int's.

AVPixelDescriptor components

All the components from the comp[] field are ordered consistently: always RGB(A) and YUV(A). This allows to identify a specific plane on a given pixel format without hard-coding knowledge of the plane order.




There is no format using it and since the ref-counting AVFrame API is in place it is not safe to directly store a pointer to AVFrame in an AVPacket. The wrapped-avframe pseudo-encoder is provided as alternative.


Before this release, the AVStream struct embedded an instance of AVCodecContext, which was used for signalling the codec parameters for that stream between libavformat and the caller. There were several major problems with this approach:

To solve those issues, a new AVCodecParameters object is introduced, and its instance is added to AVStream as AVStream.codecpar. The demuxers now export all codec parameters read from the input stream into this new object. Similarly, the caller should set the stream parameters in this object when muxing. For encoding or decoding, the caller should allocate a separate AVCodecContext object. avcodec_parameters_from_context()/avcodec_parameters_to_context() functions are provided to transfer the stream parameters between an AVCodecContext and AVCodecParameters, so that a caller can easily initialise a decoder with demuxer information, or a muxer with encoder information.


Audio/video encoding and decoding API

The previous audio and video decoding API

take one input packet (decoding) or frame (encoding) and produce either no output or one output frame (decoding) or packet (encoding). This makes it very awkward or outright impossible to handle cases where a single input produces multiple outputs. To resolve this problem, a new API with decoupled input and output is added:

The functions are the same for both audio and video and allow representing arbitrary M to N cases (i.e. M inputs may in general produce N outputs, for arbitrary M and N).

As of this release, no codecs actually require this new API to be used, but nevertheless we strongly urge all the users to update to this API as soon as possible, since it is only a metter of time before certain decoders or encoders start requiring the new API.

Bitstream filtering API

The old bitstream filtering API (av_bitstream_filter_*) had a number of major issues:

To resolve this problems, this API was completely replaced with a new API, av_bsf_*(), which:

AVCodecContext rtp_callback

This callback will be removed, it is currently non-working and has the fringe purpose of delivering the encoded frame slice by slice as they are produced. The slices order is not warranted with multithreaded encoding and it works only with the mpegvideo family of native encoders.


The function was used to generate a ref-counted packet out of a non-ref-counted one and act as no-op if the packet is already ref-counted.

av_packet_ref and av_packet_clone can be used if there is such need.


The function is superseded by av_packet_unref. It is perfectly fine to just replace every instance of av_free_packet with av_packet_unref.


This field was unused.

Global options

Several global options have been deprecated in favour of setting codec-private options.


This variable was only used to communicate key_frame, pict_type and quality to the caller, as well as a few other random fields, in a non predictable, let alone consistent way.

There was agreement that there was no use case for coded_frame, as it is a full-sized AVFrame container used for just 2-3 int-sized properties which shouldn't even belong into the AVCodecContext in the first place.

The appropriate AVPacket flag can be used instead of key_frame, while quality is exported with the new AVPacketSideData quality factor (AV_PKT_SIDE_DATA_QUALITY). There is no replacement for the other fields as they were unreliable, mishandled or just not used at all.