avfilter/formats: add type-safe functions for AVSampleFormat/AVPixelFormat lists

This avoids undefined behavior when -fshort-enums is enabled, where accessing enum arrays through int pointers causes incorrect memory reads.

Signed-off-by: niyinghao <niyinghao@xiaomi.com>
This commit is contained in:
niyinghao
2026-01-08 20:44:48 +08:00
committed by Zhao Zhili
parent 8f9700bff0
commit a5091f6d66
2 changed files with 80 additions and 7 deletions

View File

@@ -497,14 +497,18 @@ int ff_fmt_is_in(int fmt, const int *fmts)
} \
}
AVFilterFormats *ff_make_format_list(const int *fmts)
{
MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
while (count--)
formats->formats[count] = fmts[count];
#define MAKE_FORMAT_LIST_TYPE(name, type) \
AVFilterFormats *ff_make_ ## name ## _list(const type* fmts) \
{ \
MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats); \
while (count--) \
formats->formats[count] = (int)fmts[count]; \
return formats; \
}
return formats;
}
MAKE_FORMAT_LIST_TYPE(format, int)
MAKE_FORMAT_LIST_TYPE(sample_format, enum AVSampleFormat)
MAKE_FORMAT_LIST_TYPE(pixel_format, enum AVPixelFormat)
AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
{
@@ -969,6 +973,16 @@ int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
return ff_set_common_formats(ctx, ff_make_format_list(fmts));
}
int ff_set_sample_formats_from_list(AVFilterContext *ctx, const enum AVSampleFormat *fmts)
{
return ff_set_common_formats(ctx, ff_make_sample_format_list(fmts));
}
int ff_set_pixel_formats_from_list(AVFilterContext *ctx, const enum AVPixelFormat *fmts)
{
return ff_set_common_formats(ctx, ff_make_pixel_format_list(fmts));
}
#define SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, fmts, media_type, \
ref_fn, unref_fn) \
if (!fmts) \
@@ -1139,6 +1153,21 @@ int ff_set_common_formats_from_list2(const AVFilterContext *ctx,
return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_format_list(fmts));
}
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx,
AVFilterFormatsConfig **cfg_in,
AVFilterFormatsConfig **cfg_out,
const enum AVSampleFormat *fmts)
{
return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_sample_format_list(fmts));
}
int ff_set_pixel_formats_from_list2(const AVFilterContext *ctx,
AVFilterFormatsConfig **cfg_in,
AVFilterFormatsConfig **cfg_out,
const enum AVPixelFormat *fmts)
{
return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_pixel_format_list(fmts));
}
int ff_default_query_formats(AVFilterContext *ctx)
{

View File

@@ -248,6 +248,18 @@ int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats);
av_warn_unused_result
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts);
/**
* Equivalent to ff_set_common_formats(ctx, ff_make_sample_format_list(fmts))
*/
av_warn_unused_result
int ff_set_sample_formats_from_list(AVFilterContext *ctx, const enum AVSampleFormat *fmts);
/**
* Equivalent to ff_set_common_formats(ctx, ff_make_pixel_format_list(fmts))
*/
av_warn_unused_result
int ff_set_pixel_formats_from_list(AVFilterContext *ctx, const enum AVPixelFormat *fmts);
/**
* Helpers for query_formats2() which set all free audio links to the same list
* of channel layouts/sample rates. If there are no links hooked to this list,
@@ -349,6 +361,18 @@ int ff_set_common_formats_from_list2(const AVFilterContext *ctx,
AVFilterFormatsConfig **cfg_out,
const int *fmts);
av_warn_unused_result
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx,
AVFilterFormatsConfig **cfg_in,
AVFilterFormatsConfig **cfg_out,
const enum AVSampleFormat *fmts);
av_warn_unused_result
int ff_set_pixel_formats_from_list2(const AVFilterContext *ctx,
AVFilterFormatsConfig **cfg_in,
AVFilterFormatsConfig **cfg_out,
const enum AVPixelFormat *fmts);
av_warn_unused_result
int ff_add_channel_layout(AVFilterChannelLayouts **l,
const AVChannelLayout *channel_layout);
@@ -385,6 +409,26 @@ int ff_default_query_formats(AVFilterContext *ctx);
av_warn_unused_result
AVFilterFormats *ff_make_format_list(const int *fmts);
/**
* Create a list of supported sample formats. This is intended for use in
* AVFilter->query_formats().
*
* @param fmts list of enum AVSampleFormat, terminated by AV_SAMPLE_FMT_NONE
* @return the format list, with no existing references
*/
av_warn_unused_result
AVFilterFormats *ff_make_sample_format_list(const enum AVSampleFormat *fmts);
/**
* Create a list of supported pixel formats. This is intended for use in
* AVFilter->query_formats().
*
* @param fmts list of enum AVPixelFormat, terminated by AV_PIX_FMT_NONE
* @return the format list, with no existing references
*/
av_warn_unused_result
AVFilterFormats *ff_make_pixel_format_list(const enum AVPixelFormat *fmts);
/**
* Equivalent to ff_make_format_list({const int[]}{ fmt, -1 })
*/