avcodec/aom_film_grain: allocate film grain metadata dynamically
This removes the ABI breaking use of sizeof(AVFilmGrainParams), and achieves the
same size reduction to decoder structs as 08b1bffa49
.
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
24141a7140
commit
fd4a2c9b02
4 changed files with 55 additions and 13 deletions
|
@ -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,49 @@ 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_uninit_film_grain_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)) {
|
||||
av_buffer_unref(&buf);
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(fgp, &s->sets[i], sizeof(*fgp));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_aom_uninit_film_grain_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,
|
||||
|
|
|
@ -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_uninit_film_grain_params(AVFilmGrainAFGS1Params *s);
|
||||
|
||||
#endif /* AVCODEC_AOM_FILM_GRAIN_H */
|
||||
|
|
|
@ -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"
|
||||
|
@ -542,6 +543,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;
|
||||
}
|
||||
|
||||
|
@ -913,5 +922,6 @@ 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_uninit_film_grain_params(&s->aom_film_grain);
|
||||
}
|
||||
|
|
|
@ -4004,7 +4004,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;
|
||||
|
|
Loading…
Add table
Reference in a new issue