* [FFmpeg-devel] [PATCH 1/9] avcodec/Makefile: Only compile hashtable.o when needed
@ 2025-06-03 21:32 Andreas Rheinhardt
2025-06-04 6:10 ` Emma Worley
0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-06-03 21:32 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Patches attached.
- Andreas
[-- Attachment #2: 0001-avcodec-Makefile-Only-compile-hashtable.o-when-neede.patch --]
[-- Type: text/x-patch, Size: 2769 bytes --]
From 7cc1c15bb30c47edb354512fffb1f4148e7e0a9f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 21:38:41 +0200
Subject: [PATCH 1/9] avcodec/Makefile: Only compile hashtable.o when needed
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/Makefile | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fb3fb7f7f7..4d0b9c2773 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -42,7 +42,6 @@ OBJS = ac3_parser.o \
dv_profile.o \
encode.o \
get_buffer.o \
- hashtable.o \
imgconvert.o \
jni.o \
lcevcdec.o \
@@ -352,7 +351,7 @@ OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
OBJS-$(CONFIG_DXV_DECODER) += dxv.o
-OBJS-$(CONFIG_DXV_ENCODER) += dxvenc.o
+OBJS-$(CONFIG_DXV_ENCODER) += dxvenc.o hashtable.o
OBJS-$(CONFIG_EAC3_DECODER) += eac3_data.o
OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o eac3_data.o
OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o
@@ -1327,7 +1326,6 @@ TESTPROGS = avcodec \
bitstream_le \
celp_math \
codec_desc \
- hashtable \
htmlsubtitles \
jpeg2000dwt \
mathops \
@@ -1337,6 +1335,7 @@ TESTPROGS-$(CONFIG_AV1_VAAPI_ENCODER) += av1_levels
TESTPROGS-$(CONFIG_CABAC) += cabac
TESTPROGS-$(CONFIG_GOLOMB) += golomb
TESTPROGS-$(CONFIG_IDCTDSP) += dct
+TESTPROGS-$(CONFIG_DXV_ENCODER) += hashtable
TESTPROGS-$(CONFIG_IIRFILTER) += iirfilter
TESTPROGS-$(CONFIG_MJPEG_ENCODER) += mjpegenc_huffman
TESTPROGS-$(HAVE_MMX) += motion
--
2.45.2
[-- Attachment #3: 0002-avcodec-hashtable-Zero-initialize-hashtable.patch --]
[-- Type: text/x-patch, Size: 1075 bytes --]
From 16164aa30b3ae3dd4e4cb79895431f86bb049c06 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 21:42:24 +0200
Subject: [PATCH 2/9] avcodec/hashtable: Zero-initialize hashtable
Otherwise ff_hashtable_freep() would try to free uninitialized
pointers upon allocation error (which happens in the corresponding
test tool).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index 151476176b..4c7d3e18ba 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -58,7 +58,7 @@ struct FFHashtableContext {
int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t val_size, size_t max_entries)
{
- struct FFHashtableContext *res = av_malloc(sizeof(struct FFHashtableContext));
+ FFHashtableContext *res = av_mallocz(sizeof(*res));
if (!res)
return AVERROR(ENOMEM);
res->key_size = key_size;
--
2.45.2
[-- Attachment #4: 0003-tests-fate-libavcodec-Run-hashtable-test.patch --]
[-- Type: text/x-patch, Size: 1048 bytes --]
From aa330af12635009a05e9ff300ca4f7850ca531be Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 21:58:58 +0200
Subject: [PATCH 3/9] tests/fate/libavcodec: Run hashtable test
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
tests/fate/libavcodec.mak | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
index b69ad53f7c..361571aaee 100644
--- a/tests/fate/libavcodec.mak
+++ b/tests/fate/libavcodec.mak
@@ -43,6 +43,11 @@ fate-golomb: libavcodec/tests/golomb$(EXESUF)
fate-golomb: CMD = run libavcodec/tests/golomb$(EXESUF)
fate-golomb: CMP = null
+FATE_LIBAVCODEC-$(CONFIG_DXV_ENCODER) += fate-hashtable
+fate-hashtable: libavcodec/tests/hashtable$(EXESUF)
+fate-hashtable: CMD = run libavcodec/tests/hashtable$(EXESUF)
+fate-hashtable: CMP = null
+
FATE_LIBAVCODEC-$(CONFIG_IDCTDSP) += fate-idct8x8-0 fate-idct8x8-1 fate-idct8x8-2 fate-idct248
fate-idct8x8-0: libavcodec/tests/dct$(EXESUF)
--
2.45.2
[-- Attachment #5: 0004-avcodec-hashtable-Only-align-complete-entries.patch --]
[-- Type: text/x-patch, Size: 4297 bytes --]
From be43be1f8cdb18f54690da2bfbc050ab9af1614c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 22:08:46 +0200
Subject: [PATCH 4/9] avcodec/hashtable: Only align complete entries
It is unnecessary to align both key and val, as they are only accessed
via memcpy()/memcmp(), which has no alignment requirements.
We only need to ensure that that the entries as a whole
are suitable aligned for the probe sequence length.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index 4c7d3e18ba..fa79330603 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -31,9 +31,7 @@
struct FFHashtableContext {
size_t key_size;
- size_t key_size_aligned;
size_t val_size;
- size_t val_size_aligned;
size_t entry_size;
size_t max_entries;
size_t nb_entries;
@@ -51,8 +49,8 @@ struct FFHashtableContext {
*/
#define ENTRY_PSL_VAL(entry) (*(size_t*)(entry))
-#define ENTRY_KEY_PTR(entry) ((entry) + FFALIGN(sizeof(size_t), ALIGN))
-#define ENTRY_VAL_PTR(entry) (ENTRY_KEY_PTR(entry) + ctx->key_size_aligned)
+#define ENTRY_KEY_PTR(entry) ((entry) + sizeof(size_t))
+#define ENTRY_VAL_PTR(entry) (ENTRY_KEY_PTR(entry) + ctx->key_size)
#define KEYS_EQUAL(k1, k2) (!memcmp((k1), (k2), ctx->key_size))
@@ -62,12 +60,8 @@ int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t
if (!res)
return AVERROR(ENOMEM);
res->key_size = key_size;
- res->key_size_aligned = FFALIGN(key_size, ALIGN);
res->val_size = val_size;
- res->val_size_aligned = FFALIGN(val_size, ALIGN);
- res->entry_size = FFALIGN(sizeof(size_t), ALIGN)
- + res->key_size_aligned
- + res->val_size_aligned;
+ res->entry_size = FFALIGN(sizeof(size_t) + key_size + val_size, ALIGN);
res->max_entries = max_entries;
res->nb_entries = 0;
res->crc = av_crc_get_table(AV_CRC_32_IEEE);
@@ -81,7 +75,7 @@ int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t
return AVERROR(ENOMEM);
}
- res->swapbuf = av_calloc(2, res->key_size_aligned + res->val_size_aligned);
+ res->swapbuf = av_calloc(2, res->key_size + res->val_size);
if (!res->swapbuf) {
ff_hashtable_freep(&res);
return AVERROR(ENOMEM);
@@ -124,10 +118,10 @@ int ff_hashtable_set(struct FFHashtableContext *ctx, const void *key, const void
size_t hash = hash_key(ctx, key);
size_t wrapped_index = hash % ctx->max_entries;
uint8_t *set = ctx->swapbuf;
- uint8_t *tmp = ctx->swapbuf + ctx->key_size_aligned + ctx->val_size_aligned;
+ uint8_t *tmp = ctx->swapbuf + ctx->key_size + ctx->val_size;
memcpy(set, key, ctx->key_size);
- memcpy(set + ctx->key_size_aligned, val, ctx->val_size);
+ memcpy(set + ctx->key_size, val, ctx->val_size);
for (size_t i = 0; i < ctx->max_entries; i++) {
if (++wrapped_index == ctx->max_entries)
@@ -137,7 +131,7 @@ int ff_hashtable_set(struct FFHashtableContext *ctx, const void *key, const void
if (!ENTRY_PSL_VAL(entry))
ctx->nb_entries++;
ENTRY_PSL_VAL(entry) = psl;
- memcpy(ENTRY_KEY_PTR(entry), set, ctx->key_size_aligned + ctx->val_size);
+ memcpy(ENTRY_KEY_PTR(entry), set, ctx->key_size + ctx->val_size);
return 1;
}
if (ENTRY_PSL_VAL(entry) < psl) {
@@ -151,8 +145,8 @@ int ff_hashtable_set(struct FFHashtableContext *ctx, const void *key, const void
// PSL of the inserted entry.
swapping = 1;
// set needs to swap with entry
- memcpy(tmp, ENTRY_KEY_PTR(entry), ctx->key_size_aligned + ctx->val_size_aligned);
- memcpy(ENTRY_KEY_PTR(entry), set, ctx->key_size_aligned + ctx->val_size_aligned);
+ memcpy(tmp, ENTRY_KEY_PTR(entry), ctx->key_size + ctx->val_size);
+ memcpy(ENTRY_KEY_PTR(entry), set, ctx->key_size + ctx->val_size);
FFSWAP(uint8_t*, set, tmp);
FFSWAP(size_t, psl, ENTRY_PSL_VAL(entry));
}
--
2.45.2
[-- Attachment #6: 0005-avcodec-hashtable-Check-for-overflow.patch --]
[-- Type: text/x-patch, Size: 1374 bytes --]
From 3407a2d3aa03360af4c7ad5037908946843ed3dc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 22:35:03 +0200
Subject: [PATCH 5/9] avcodec/hashtable: Check for overflow
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index fa79330603..ec8eca471f 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -56,12 +56,18 @@ struct FFHashtableContext {
int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t val_size, size_t max_entries)
{
+ const size_t keyval_size = key_size + val_size;
+
+ if (keyval_size < key_size || // did (unsigned,defined) wraparound happen?
+ keyval_size > SIZE_MAX - sizeof(size_t) - (ALIGN - 1))
+ return AVERROR(ERANGE);
+
FFHashtableContext *res = av_mallocz(sizeof(*res));
if (!res)
return AVERROR(ENOMEM);
res->key_size = key_size;
res->val_size = val_size;
- res->entry_size = FFALIGN(sizeof(size_t) + key_size + val_size, ALIGN);
+ res->entry_size = FFALIGN(sizeof(size_t) + keyval_size, ALIGN);
res->max_entries = max_entries;
res->nb_entries = 0;
res->crc = av_crc_get_table(AV_CRC_32_IEEE);
--
2.45.2
[-- Attachment #7: 0006-avcodec-hashtable-Combine-allocations.patch --]
[-- Type: text/x-patch, Size: 1960 bytes --]
From 5437b460944bd27da9026b3a0edc0db69dea5275 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 22:44:41 +0200
Subject: [PATCH 6/9] avcodec/hashtable: Combine allocations
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index ec8eca471f..9b37ce3d69 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -37,7 +37,7 @@ struct FFHashtableContext {
size_t nb_entries;
const AVCRC *crc;
uint8_t *table;
- uint8_t *swapbuf;
+ uint8_t swapbuf[];
};
/*
@@ -59,10 +59,11 @@ int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t
const size_t keyval_size = key_size + val_size;
if (keyval_size < key_size || // did (unsigned,defined) wraparound happen?
- keyval_size > SIZE_MAX - sizeof(size_t) - (ALIGN - 1))
+ keyval_size > FFMIN(SIZE_MAX - sizeof(size_t) - (ALIGN - 1),
+ (SIZE_MAX - sizeof(FFHashtableContext)) / 2))
return AVERROR(ERANGE);
- FFHashtableContext *res = av_mallocz(sizeof(*res));
+ FFHashtableContext *res = av_mallocz(sizeof(*res) + 2 * keyval_size);
if (!res)
return AVERROR(ENOMEM);
res->key_size = key_size;
@@ -81,11 +82,6 @@ int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t
return AVERROR(ENOMEM);
}
- res->swapbuf = av_calloc(2, res->key_size + res->val_size);
- if (!res->swapbuf) {
- ff_hashtable_freep(&res);
- return AVERROR(ENOMEM);
- }
*ctx = res;
return 0;
}
@@ -208,7 +204,6 @@ void ff_hashtable_freep(struct FFHashtableContext **ctx)
{
if (*ctx) {
av_freep(&(*ctx)->table);
- av_freep(&(*ctx)->swapbuf);
}
av_freep(ctx);
}
--
2.45.2
[-- Attachment #8: 0007-avcodec-hashtable-Mark-alloc-free-functions-as-av_co.patch --]
[-- Type: text/x-patch, Size: 1554 bytes --]
From 1ad8db9dcd8c0e153477d87111af079fbe344f39 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 22:47:26 +0200
Subject: [PATCH 7/9] avcodec/hashtable: Mark alloc,free functions as av_cold
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index 9b37ce3d69..0e9b3d88c2 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -22,8 +22,10 @@
#include <stdint.h>
#include <string.h>
+#include "libavutil/attributes.h"
#include "libavutil/crc.h"
#include "libavutil/error.h"
+#include "libavutil/macros.h"
#include "libavutil/mem.h"
#include "hashtable.h"
@@ -54,7 +56,8 @@ struct FFHashtableContext {
#define KEYS_EQUAL(k1, k2) (!memcmp((k1), (k2), ctx->key_size))
-int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t val_size, size_t max_entries)
+av_cold int ff_hashtable_alloc(FFHashtableContext **ctx, size_t key_size,
+ size_t val_size, size_t max_entries)
{
const size_t keyval_size = key_size + val_size;
@@ -200,7 +203,7 @@ void ff_hashtable_clear(struct FFHashtableContext *ctx)
memset(ctx->table, 0, ctx->entry_size * ctx->max_entries);
}
-void ff_hashtable_freep(struct FFHashtableContext **ctx)
+av_cold void ff_hashtable_freep(FFHashtableContext **ctx)
{
if (*ctx) {
av_freep(&(*ctx)->table);
--
2.45.2
[-- Attachment #9: 0008-avcodec-hashtable-Only-free-buffer-if-there-is-buffe.patch --]
[-- Type: text/x-patch, Size: 756 bytes --]
From 5aca3c9d1c7e981006205c7d74bff7a4707a81e7 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 22:50:32 +0200
Subject: [PATCH 8/9] avcodec/hashtable: Only free buffer if there is buffer to
free
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index 0e9b3d88c2..0d5c816cd7 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -207,6 +207,6 @@ av_cold void ff_hashtable_freep(FFHashtableContext **ctx)
{
if (*ctx) {
av_freep(&(*ctx)->table);
+ av_freep(ctx);
}
- av_freep(ctx);
}
--
2.45.2
[-- Attachment #10: 0009-avcodec-hashtable-Remove-null-statement.patch --]
[-- Type: text/x-patch, Size: 737 bytes --]
From ca0cfc25b57a097221334316bc09384476840a6c Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Tue, 3 Jun 2025 23:18:21 +0200
Subject: [PATCH 9/9] avcodec/hashtable: Remove null statement
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/hashtable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c
index 0d5c816cd7..d18e872f4f 100644
--- a/libavcodec/hashtable.c
+++ b/libavcodec/hashtable.c
@@ -194,7 +194,7 @@ int ff_hashtable_delete(struct FFHashtableContext *ctx, const void *key)
entry = next_entry;
}
}
- };
+ }
return 0;
}
--
2.45.2
[-- Attachment #11: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/9] avcodec/Makefile: Only compile hashtable.o when needed
2025-06-03 21:32 [FFmpeg-devel] [PATCH 1/9] avcodec/Makefile: Only compile hashtable.o when needed Andreas Rheinhardt
@ 2025-06-04 6:10 ` Emma Worley
0 siblings, 0 replies; 2+ messages in thread
From: Emma Worley @ 2025-06-04 6:10 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Tue, Jun 3, 2025 at 2:32 PM Andreas Rheinhardt
<andreas.rheinhardt@outlook.com> wrote:
>
> Patches attached.
>
> - Andreas
All lgtm, thanks for the cleanup.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-06-04 6:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-03 21:32 [FFmpeg-devel] [PATCH 1/9] avcodec/Makefile: Only compile hashtable.o when needed Andreas Rheinhardt
2025-06-04 6:10 ` Emma Worley
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git