This means that one only needs to update the shorter list of references. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- I doubt that this optimizations is worth the additional complexity. I have just added it for you to decide.
libavfilter/formats.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 9788357952..4ac690ea8a 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -33,12 +33,23 @@ /** * Add all refs from a to ret and destroy a. + * The macro may swap ret and a internally, but the combined list is in ret. + * If preserve_fmts is set, the fmts array is preserved when swapping. */ -#define MERGE_REF(ret, a, fmts, type, fail_statement) \ +#define MERGE_REF(ret, a, fmts, type, preserve_fmts, fail_statement) \ do { \ type ***tmp; \ int i; \ \ + if (ret->refcount < a->refcount) { \ + FFSWAP(type *, ret, a); \ + if (preserve_fmts) { \ + FFSWAP(type, *ret, *a); \ + FFSWAP(unsigned, ret->refcount, a->refcount); \ + FFSWAP(type ***, ret->refs, a->refs); \ + } \ + } \ + \ if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \ sizeof(*tmp)))) \ { fail_statement } \ @@ -60,6 +71,7 @@ do { \ * the formats are compatible. * If empty_allowed is set and one of a,b->nb is zero, the lists are * merged; otherwise, it is treated as error. + * The macro may swap a and b internally, but the combined list is in a. */ #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \ do { \ @@ -94,7 +106,7 @@ do { a->fmts = tmp; \ \ merge_ref: \ - MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \ + MERGE_REF(a, b, fmts, type, 1, return AVERROR(ENOMEM);); \ } while (0) static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b, @@ -199,7 +211,8 @@ int ff_merge_channel_layouts(AVFilterChannelLayouts *a, return 0; b->nb_channel_layouts = j; } - MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM);); + MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, + 1, return AVERROR(ENOMEM);); return 1; } @@ -248,10 +261,7 @@ int ff_merge_channel_layouts(AVFilterChannelLayouts *a, return 0; } - if (a->refcount > b->refcount) - FFSWAP(AVFilterChannelLayouts *, a, b); - - MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, + MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, 0, { av_free(channel_layouts); return AVERROR(ENOMEM); }); av_freep(&b->channel_layouts); b->channel_layouts = channel_layouts; -- 2.20.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".