From b9abdd9eaa4ae7fe7c2d3512444bf9bd7a56e138 Mon Sep 17 00:00:00 2001 From: James Almer Date: Fri, 25 Oct 2024 12:49:11 -0300 Subject: [PATCH] avcodec/h2645_sei: use the RefStruct API for film_grain_characteristics And ensure the buffer is synced between threads. Based on a patch by Dale Curtis Signed-off-by: James Almer (cherry picked from commit e33b162c7d8bbbb4838a2af3685fad2bb1ac774a) --- libavcodec/h2645_sei.c | 15 ++++++++++++--- libavcodec/h2645_sei.h | 4 +++- libavcodec/h264_sei.c | 1 - libavcodec/h264_slice.c | 5 ++++- libavcodec/hevc/hevcdec.c | 9 +++++---- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c index 15e867b5ed..62369dd37f 100644 --- a/libavcodec/h2645_sei.c +++ b/libavcodec/h2645_sei.c @@ -42,6 +42,7 @@ #include "golomb.h" #include "h2645_sei.h" #include "itut35.h" +#include "refstruct.h" #define IS_H264(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_H264 : CONFIG_H264_SEI) #define IS_HEVC(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_HEVC : CONFIG_HEVC_SEI) @@ -495,7 +496,11 @@ int ff_h2645_sei_message_decode(H2645SEI *h, enum SEIType type, case SEI_TYPE_DISPLAY_ORIENTATION: return decode_display_orientation(&h->display_orientation, gb); case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: - return decode_film_grain_characteristics(&h->film_grain_characteristics, codec_id, gb); + ff_refstruct_unref(&h->film_grain_characteristics); + h->film_grain_characteristics = ff_refstruct_allocz(sizeof(*h->film_grain_characteristics)); + if (!h->film_grain_characteristics) + return AVERROR(ENOMEM); + return decode_film_grain_characteristics(h->film_grain_characteristics, codec_id, gb); case SEI_TYPE_FRAME_PACKING_ARRANGEMENT: return decode_frame_packing_arrangement(&h->frame_packing, gb, codec_id); case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: @@ -551,6 +556,9 @@ int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src) } dst->aom_film_grain.enable = src->aom_film_grain.enable; + ff_refstruct_replace(&dst->film_grain_characteristics, + src->film_grain_characteristics); + return 0; } @@ -820,8 +828,8 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei, return ret; } - if (sei->film_grain_characteristics.present) { - H2645SEIFilmGrainCharacteristics *fgc = &sei->film_grain_characteristics; + if (sei->film_grain_characteristics && sei->film_grain_characteristics->present) { + H2645SEIFilmGrainCharacteristics *fgc = sei->film_grain_characteristics; AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame); AVFilmGrainH274Params *h274; @@ -923,5 +931,6 @@ void ff_h2645_sei_reset(H2645SEI *s) s->mastering_display.present = 0; s->content_light.present = 0; + ff_refstruct_unref(&s->film_grain_characteristics); ff_aom_uninit_film_grain_params(&s->aom_film_grain); } diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h index 598f78b585..abc49760d9 100644 --- a/libavcodec/h2645_sei.h +++ b/libavcodec/h2645_sei.h @@ -135,11 +135,13 @@ typedef struct H2645SEI { H2645SEIFramePacking frame_packing; H2645SEIDisplayOrientation display_orientation; H2645SEIAlternativeTransfer alternative_transfer; - H2645SEIFilmGrainCharacteristics film_grain_characteristics; H2645SEIAmbientViewingEnvironment ambient_viewing_environment; H2645SEIMasteringDisplay mastering_display; H2645SEIContentLight content_light; AVFilmGrainAFGS1Params aom_film_grain; + + // Dynamic allocations due to large size. + H2645SEIFilmGrainCharacteristics *film_grain_characteristics; } H2645SEI; enum { diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 8d6dc77943..15a5232209 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -55,7 +55,6 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->picture_timing.present = 0; h->buffering_period.present = 0; h->common.frame_packing.present = 0; - h->common.film_grain_characteristics.present = 0; h->common.display_orientation.present = 0; h->common.afd.present = 0; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a66b75ca80..84595b1a8b 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -516,7 +516,10 @@ static int h264_frame_start(H264Context *h) pic->f->crop_top = h->crop_top; pic->f->crop_bottom = h->crop_bottom; - pic->needs_fg = h->sei.common.film_grain_characteristics.present && !h->avctx->hwaccel && + pic->needs_fg = + h->sei.common.film_grain_characteristics && + h->sei.common.film_grain_characteristics->present && + !h->avctx->hwaccel && !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN); if ((ret = alloc_picture(h, pic)) < 0) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 7f1079c669..5dc605f91f 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -411,7 +411,7 @@ static int export_stream_params_from_sei(HEVCContext *s) avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics; } - if (s->sei.common.film_grain_characteristics.present || + if ((s->sei.common.film_grain_characteristics && s->sei.common.film_grain_characteristics->present) || s->sei.common.aom_film_grain.enable) avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN; @@ -3236,7 +3236,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l, else s->cur_frame->f->flags &= ~AV_FRAME_FLAG_KEY; - s->cur_frame->needs_fg = (s->sei.common.film_grain_characteristics.present || + s->cur_frame->needs_fg = ((s->sei.common.film_grain_characteristics && + s->sei.common.film_grain_characteristics->present) || s->sei.common.aom_film_grain.enable) && !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && !s->avctx->hwaccel; @@ -3246,8 +3247,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l, goto fail; if (s->cur_frame->needs_fg && - (s->sei.common.film_grain_characteristics.present && - !ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics.model_id, + (s->sei.common.film_grain_characteristics && s->sei.common.film_grain_characteristics->present && + !ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics->model_id, s->cur_frame->f->format) || !av_film_grain_params_select(s->cur_frame->f))) { av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown,