[FFmpeg-devel] ABI break in 4.3

Jan Engelhardt jengelh at inai.de
Sun Jul 5 11:43:37 EEST 2020


On Sunday 2020-07-05 01:04, James Almer wrote:
>On 7/4/2020 7:54 PM, Jan Engelhardt wrote:
>> @@ -67,6 +67,10 @@ typedef struct AVDCT {
>> +
>> +    void (*get_pixels_unaligned)(int16_t *block /* align 16 */,
>> +                       const uint8_t *pixels,
>> +                       ptrdiff_t line_size);
>>  } AVDCT;
>
>Neither of these are breaks as sizeof(AVCodecContext) and sizeof(AVDCT)
>are not part of the ABI. Both structs are meant to be allocated using
>avcodec_alloc_context3() and avcodec_dct_alloc() respectively, and not
>stored on stack or allocated with av_malloc(sizeof()).

There is sometimes a disconnect between how an API is meant to be 
used, and how 3rd party programs actually use it. In the spirit of 
making it "hard(er) to misuse", perhaps the struct definition should be 
removed from the public header and instead be written as

	struct AVDCT;
	typedef struct AVDCT AVDCT;

so as to rule out av_malloc(sizeof(AVDCT)).


>[[the header file says:
> * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user
> * applications.]]

A "can" can be read as "need not". Perhaps that is what we are seeing with
blender which seems to access av fields directly, and has no noticable 
av_set_ calls.

writeffmpeg.c:  if ((of->oformat->flags & AVFMT_GLOBALHEADER)) {
writeffmpeg.c:  if (of->oformat->flags & AVFMT_GLOBALHEADER) {
writeffmpeg.c:  of->oformat = fmt;
writeffmpeg.c:    of->packet_size = rd->ffcodecdata.mux_packet_size;
writeffmpeg.c:  of->max_delay = (int)(0.7 * AV_TIME_BASE);
writeffmpeg.c:  BLI_strncpy(of->filename, name, sizeof(of->filename));
writeffmpeg.c:    if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
writeffmpeg.c:        &of->metadata, context->stamp_data, ffmpeg_add_metadata_callback, false);
writeffmpeg.c:  if (of->pb) {
writeffmpeg.c:    avio_close(of->pb);

Or, summarized: A program may have been built with 4.3 but is combined
with 4.2.3 at runtime, then this can happen:

	a = avcodec_dct_alloc(); // allocates 896
#ifdef HAVE_STRUCT_AVDCT_GET_PIXELS_UNALIGNED
	a->get_pixels_unaligned = ffunc; // boom accessing byte ~952
#endif

If the API should not be used this way, it should not offer this way.


More information about the ffmpeg-devel mailing list