[FFmpeg-devel] libdav1d: use film grain export flag to export AVFilmGrainParams side data
James Almer
jamrial at gmail.com
Thu Nov 12 15:49:34 EET 2020
On 11/12/2020 8:59 AM, Lynne wrote:
> This patch is relatively straightforward with one exception:
> the decoder option flag.
> The option was introduced to troubleshoot but its existence is conflicting
> and redundant now that we have a codec-generic flag.
> Hence this patch deprecates it.
>
> The way it interacts with AV_CODEC_EXPORT_DATA_FILM_GRAIN is as follows:
>
> If filmgrain is unset and AV_CODEC_EXPORT_DATA_FILM_GRAIN is
> present, disable film grain application and export side data.
>
> If filmgrain is set to 0, disable film grain and export side data.
>
> If filmgrain is set to 1, apply film grain but export side data if
> the AV_CODEC_EXPORT_DATA_FILM_GRAIN flag is set. This may result in
> double film grain application, but the user has requested it by setting
> both.
>
> Patch attached.
> From 2e1c64a6d2078d606dbfd088d640678cd0278ede Mon Sep 17 00:00:00 2001
> From: Lynne <dev at lynne.ee>
> Date: Thu, 12 Nov 2020 12:48:20 +0100
> Subject: [PATCH 2/2] libdav1d: use film grain export flag to export
> AVFilmGrainParams side data
>
> This patch is relatively straightforward with one exception:
> the decoder option flag.
> The option was introduced to troubleshoot but its existence is conflicting
> and redundant now that we have a codec-generic flag.
> Hence this patch deprecates it.
>
> The way it interacts with AV_CODEC_EXPORT_DATA_FILM_GRAIN is as follows:
>
> If filmgrain is unset and AV_CODEC_EXPORT_DATA_FILM_GRAIN is
> present, disable film grain application and export side data.
>
> If filmgrain is set to 0, disable film grain and export side data.
>
> If filmgrain is set to 1, apply film grain but export side data if
> the AV_CODEC_EXPORT_DATA_FILM_GRAIN flag is set. This may result in
> double film grain application, but the user has requested it by setting
> both.
> ---
> libavcodec/libdav1d.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 66 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
> index 3af7ef4edc..1aab3da751 100644
> --- a/libavcodec/libdav1d.c
> +++ b/libavcodec/libdav1d.c
> @@ -22,6 +22,7 @@
> #include <dav1d/dav1d.h>
>
> #include "libavutil/avassert.h"
> +#include "libavutil/film_grain_params.h"
> #include "libavutil/mastering_display_metadata.h"
> #include "libavutil/imgutils.h"
> #include "libavutil/opt.h"
> @@ -37,6 +38,7 @@ typedef struct Libdav1dContext {
> Dav1dContext *c;
> AVBufferPool *pool;
> int pool_size;
> + AVBufferRef *film_grain_params;
>
> Dav1dData data;
> int tile_threads;
> @@ -135,6 +137,10 @@ static av_cold int libdav1d_init(AVCodecContext *c)
> s.allocator.alloc_picture_callback = libdav1d_picture_allocator;
> s.allocator.release_picture_callback = libdav1d_picture_release;
> s.frame_size_limit = c->max_pixels;
> +
> + if (dav1d->apply_grain < 0 &&
> + c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)
> + dav1d->apply_grain = 0;
Don't overwrite a Libdav1dContext field that was set by an AVOption.
Instead, just change the check below and set s.apply_grain directly
based on both user options (film_grain and export_side_data).
> if (dav1d->apply_grain >= 0)
> s.apply_grain = dav1d->apply_grain;
>
> @@ -395,6 +401,64 @@ FF_ENABLE_DEPRECATION_WARNINGS
> break;
> }
> }
> + if ((!dav1d->apply_grain || (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) &&
With the above you should in theory be able to just check for the
export_side_data flag and frame_hdr->film_grain.present here.
> + p->frame_hdr->film_grain.present) {
> + if (p->frame_hdr->film_grain.update) {
> + AVFilmGrainParams *fgp;
> +
> + av_buffer_unref(&dav1d->film_grain_params);
> + dav1d->film_grain_params = av_film_grain_params_buffer_alloc();
> + if (!dav1d->film_grain_params) {
> + res = AVERROR(ENOMEM);
> + goto fail;
> + }
> +
> + fgp = (AVFilmGrainParams *)dav1d->film_grain_params->data;
> +
> + fgp->type = AV_FILM_GRAM_PARAMS_AV1;
> + fgp->seed = p->frame_hdr->film_grain.data.seed;
> + fgp->num_y_points = p->frame_hdr->film_grain.data.num_y_points;
> + fgp->chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma;
> + fgp->scaling_shift = p->frame_hdr->film_grain.data.scaling_shift;
> + fgp->ar_coeff_lag = p->frame_hdr->film_grain.data.ar_coeff_lag;
> + fgp->ar_coeff_shift = p->frame_hdr->film_grain.data.ar_coeff_shift;
> + fgp->grain_scale_shift = p->frame_hdr->film_grain.data.grain_scale_shift;
> + fgp->overlap_flag = p->frame_hdr->film_grain.data.overlap_flag;
> + fgp->clip_to_limited_range = p->frame_hdr->film_grain.data.clip_to_restricted_range;
> +
> + memcpy(&fgp->y_points, &p->frame_hdr->film_grain.data.y_points,
> + sizeof(fgp->y_points));
> + memcpy(&fgp->num_uv_points, &p->frame_hdr->film_grain.data.num_uv_points,
> + sizeof(fgp->num_uv_points));
> + memcpy(&fgp->uv_points, &p->frame_hdr->film_grain.data.uv_points,
> + sizeof(fgp->uv_points));
> + memcpy(&fgp->ar_coeffs_y, &p->frame_hdr->film_grain.data.ar_coeffs_y,
> + sizeof(fgp->ar_coeffs_y));
> + memcpy(&fgp->ar_coeffs_uv, &p->frame_hdr->film_grain.data.ar_coeffs_uv,
> + sizeof(fgp->ar_coeffs_uv));
> + memcpy(&fgp->uv_mult, &p->frame_hdr->film_grain.data.uv_mult,
> + sizeof(fgp->uv_mult));
> + memcpy(&fgp->uv_mult_luma, &p->frame_hdr->film_grain.data.uv_luma_mult,
> + sizeof(fgp->uv_mult_luma));
> + memcpy(&fgp->uv_offset, &p->frame_hdr->film_grain.data.uv_offset,
> + sizeof(fgp->uv_offset));
> + }
> +
> + if (dav1d->film_grain_params) {
> + AVBufferRef *fgp_ref = av_buffer_ref(dav1d->film_grain_params);
> + if (!fgp_ref) {
> + res = AVERROR(ENOMEM);
> + goto fail;
> + }
> + if (!av_frame_new_side_data_from_buf(frame,
> + AV_FRAME_DATA_FILM_GRAIN_PARAMS,
> + fgp_ref)) {
> + av_buffer_unref(&fgp_ref);
> + res = AVERROR(ENOMEM);
> + goto fail;
> + }
> + }
> + }
>
> res = 0;
> fail:
> @@ -408,6 +472,7 @@ static av_cold int libdav1d_close(AVCodecContext *c)
> {
> Libdav1dContext *dav1d = c->priv_data;
>
> + av_buffer_unref(&dav1d->film_grain_params);
> av_buffer_pool_uninit(&dav1d->pool);
> dav1d_data_unref(&dav1d->data);
> dav1d_close(&dav1d->c);
> @@ -420,7 +485,7 @@ static av_cold int libdav1d_close(AVCodecContext *c)
> static const AVOption libdav1d_options[] = {
> { "tilethreads", "Tile threads", OFFSET(tile_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_TILE_THREADS, VD },
> { "framethreads", "Frame threads", OFFSET(frame_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_THREADS, VD },
> - { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD },
> + { "filmgrain", "Apply Film Grain (deprecated)", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD },
> { "oppoint", "Select an operating point of the scalable bitstream", OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
> { "alllayers", "Output all spatial layers", OFFSET(all_layers), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
> { NULL }
> --
> 2.29.2
>
More information about the ffmpeg-devel
mailing list