[FFmpeg-devel] [PATCH 6/7] avfilter/formats: Always keep longer references list when merging lists
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Sat Aug 15 08:48:15 EEST 2020
This means that one only needs to update the shorter list of references.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at 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
More information about the ffmpeg-devel
mailing list