[FFmpeg-devel] [PATCH 2/5] avcodec/aom_film_grain: allocate film grain metadata dynamically
James Almer
jamrial at gmail.com
Fri Oct 25 05:26:10 EEST 2024
This removes the ABI breaking use of sizeof(AVFilmGrainParams), and achieves the
same size reduction to decoder structs as 08b1bffa49715a9615acc025dfbea252d8409e1f.
Signed-off-by: James Almer <jamrial at gmail.com>
---
libavcodec/aom_film_grain.c | 47 +++++++++++++++++++++++++++++--------
libavcodec/aom_film_grain.h | 6 ++++-
libavcodec/h2645_sei.c | 12 +++++++++-
libavcodec/hevc/hevcdec.c | 1 -
4 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/libavcodec/aom_film_grain.c b/libavcodec/aom_film_grain.c
index e302567ba5..de4437fd16 100644
--- a/libavcodec/aom_film_grain.c
+++ b/libavcodec/aom_film_grain.c
@@ -26,7 +26,9 @@
*/
#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
#include "aom_film_grain.h"
#include "get_bits.h"
@@ -124,7 +126,7 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
{
GetBitContext gbc, *gb = &gbc;
AVFilmGrainAOMParams *aom;
- AVFilmGrainParams *fgp, *ref = NULL;
+ AVFilmGrainParams *fgp = NULL, *ref = NULL;
int ret, num_sets, n, i, uv, num_y_coeffs, update_grain, luma_only;
ret = init_get_bits8(gb, payload, payload_size);
@@ -135,28 +137,38 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
if (!s->enable)
return 0;
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->sets); i++)
+ av_buffer_unref(&s->sets[i]);
+
skip_bits(gb, 4); // reserved
num_sets = get_bits(gb, 3) + 1;
for (n = 0; n < num_sets; n++) {
int payload_4byte, payload_size, set_idx, apply_units_log2, vsc_flag;
int predict_scaling, predict_y_scaling, predict_uv_scaling[2];
int payload_bits, start_position;
+ size_t fgp_size;
start_position = get_bits_count(gb);
payload_4byte = get_bits1(gb);
payload_size = get_bits(gb, payload_4byte ? 2 : 8);
set_idx = get_bits(gb, 3);
- fgp = &s->sets[set_idx];
+ fgp = av_film_grain_params_alloc(&fgp_size);
+ if (!fgp)
+ goto error;
aom = &fgp->codec.aom;
fgp->type = get_bits1(gb) ? AV_FILM_GRAIN_PARAMS_AV1 : AV_FILM_GRAIN_PARAMS_NONE;
- if (!fgp->type)
+ if (!fgp->type) {
+ av_freep(&fgp);
continue;
+ }
fgp->seed = get_bits(gb, 16);
update_grain = get_bits1(gb);
- if (!update_grain)
+ if (!update_grain) {
+ av_freep(&fgp);
continue;
+ }
apply_units_log2 = get_bits(gb, 4);
fgp->width = get_bits(gb, 12) << apply_units_log2;
@@ -330,32 +342,47 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
if (payload_bits > payload_size * 8)
goto error;
skip_bits(gb, payload_size * 8 - payload_bits);
+
+ av_buffer_unref(&s->sets[set_idx]);
+ s->sets[set_idx] = av_buffer_create((uint8_t *)fgp, fgp_size, NULL, NULL, 0);
+ if (!s->sets[set_idx])
+ goto error;
}
return 0;
error:
- memset(s, 0, sizeof(*s));
+ av_free(fgp);
+ ff_aom_film_grain_uninit_params(s);
return AVERROR_INVALIDDATA;
}
int ff_aom_attach_film_grain_sets(const AVFilmGrainAFGS1Params *s, AVFrame *frame)
{
- AVFilmGrainParams *fgp;
if (!s->enable)
return 0;
for (int i = 0; i < FF_ARRAY_ELEMS(s->sets); i++) {
- if (s->sets[i].type != AV_FILM_GRAIN_PARAMS_AV1)
+ AVBufferRef *buf;
+
+ if (!s->sets[i])
continue;
- fgp = av_film_grain_params_create_side_data(frame);
- if (!fgp)
+
+ buf = av_buffer_ref(s->sets[i]);
+ if (!buf || !av_frame_new_side_data_from_buf(frame,
+ AV_FRAME_DATA_FILM_GRAIN_PARAMS, buf))
return AVERROR(ENOMEM);
- memcpy(fgp, &s->sets[i], sizeof(*fgp));
}
return 0;
}
+void ff_aom_film_grain_uninit_params(AVFilmGrainAFGS1Params *s)
+{
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->sets); i++)
+ av_buffer_unref(&s->sets[i]);
+ s->enable = 0;
+}
+
// Taken from the AV1 spec. Range is [-2048, 2047], mean is 0 and stddev is 512
static const int16_t gaussian_sequence[2048] = {
56, 568, -180, 172, 124, -84, 172, -64, -900, 24, 820,
diff --git a/libavcodec/aom_film_grain.h b/libavcodec/aom_film_grain.h
index 1f8c78f657..94cd9d9f67 100644
--- a/libavcodec/aom_film_grain.h
+++ b/libavcodec/aom_film_grain.h
@@ -28,11 +28,12 @@
#ifndef AVCODEC_AOM_FILM_GRAIN_H
#define AVCODEC_AOM_FILM_GRAIN_H
+#include "libavutil/buffer.h"
#include "libavutil/film_grain_params.h"
typedef struct AVFilmGrainAFGS1Params {
int enable;
- AVFilmGrainParams sets[8];
+ AVBufferRef *sets[8];
} AVFilmGrainAFGS1Params;
// Synthesizes film grain on top of `in` and stores the result to `out`. `out`
@@ -48,4 +49,7 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
// Attach all valid film grain param sets to `frame`.
int ff_aom_attach_film_grain_sets(const AVFilmGrainAFGS1Params *s, AVFrame *frame);
+// Free all allocations in `s` and zero the entire struct.
+void ff_aom_film_grain_uninit_params(AVFilmGrainAFGS1Params *s);
+
#endif /* AVCODEC_AOM_FILM_GRAIN_H */
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index a481dbca2c..33390d389d 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -26,6 +26,7 @@
#include "config_components.h"
#include "libavutil/ambient_viewing_environment.h"
+#include "libavutil/buffer.h"
#include "libavutil/display.h"
#include "libavutil/hdr_dynamic_metadata.h"
#include "libavutil/film_grain_params.h"
@@ -547,6 +548,14 @@ int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src)
}
}
+ for (unsigned i = 0; i < FF_ARRAY_ELEMS(dst->aom_film_grain.sets); i++) {
+ ret = av_buffer_replace(&dst->aom_film_grain.sets[i],
+ src->aom_film_grain.sets[i]);
+ if (ret < 0)
+ return ret;
+ }
+ dst->aom_film_grain.enable = src->aom_film_grain.enable;
+
return 0;
}
@@ -918,7 +927,8 @@ void ff_h2645_sei_reset(H2645SEI *s)
s->ambient_viewing_environment.present = 0;
s->mastering_display.present = 0;
s->content_light.present = 0;
- s->aom_film_grain.enable = 0;
+
+ ff_aom_film_grain_uninit_params(&s->aom_film_grain);
av_freep(&s->film_grain_characteristics);
}
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 900895598f..f2bdf6134e 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -4010,7 +4010,6 @@ static int hevc_update_thread_context(AVCodecContext *dst,
s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer;
s->sei.common.mastering_display = s0->sei.common.mastering_display;
s->sei.common.content_light = s0->sei.common.content_light;
- s->sei.common.aom_film_grain = s0->sei.common.aom_film_grain;
s->sei.tdrdi = s0->sei.tdrdi;
return 0;
--
2.47.0
More information about the ffmpeg-devel
mailing list