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 <dalecurtis@chromium.org>

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2024-10-25 12:49:11 -03:00
parent fd4a2c9b02
commit e33b162c7d
5 changed files with 24 additions and 10 deletions

View file

@ -42,6 +42,7 @@
#include "golomb.h" #include "golomb.h"
#include "h2645_sei.h" #include "h2645_sei.h"
#include "itut35.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_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) #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: case SEI_TYPE_DISPLAY_ORIENTATION:
return decode_display_orientation(&h->display_orientation, gb); return decode_display_orientation(&h->display_orientation, gb);
case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: 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: case SEI_TYPE_FRAME_PACKING_ARRANGEMENT:
return decode_frame_packing_arrangement(&h->frame_packing, gb, codec_id); return decode_frame_packing_arrangement(&h->frame_packing, gb, codec_id);
case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: 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; dst->aom_film_grain.enable = src->aom_film_grain.enable;
ff_refstruct_replace(&dst->film_grain_characteristics,
src->film_grain_characteristics);
return 0; return 0;
} }
@ -820,8 +828,8 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
return ret; return ret;
} }
if (sei->film_grain_characteristics.present) { if (sei->film_grain_characteristics && sei->film_grain_characteristics->present) {
H2645SEIFilmGrainCharacteristics *fgc = &sei->film_grain_characteristics; H2645SEIFilmGrainCharacteristics *fgc = sei->film_grain_characteristics;
AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame); AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
AVFilmGrainH274Params *h274; AVFilmGrainH274Params *h274;
@ -923,5 +931,6 @@ void ff_h2645_sei_reset(H2645SEI *s)
s->mastering_display.present = 0; s->mastering_display.present = 0;
s->content_light.present = 0; s->content_light.present = 0;
ff_refstruct_unref(&s->film_grain_characteristics);
ff_aom_uninit_film_grain_params(&s->aom_film_grain); ff_aom_uninit_film_grain_params(&s->aom_film_grain);
} }

View file

@ -135,11 +135,13 @@ typedef struct H2645SEI {
H2645SEIFramePacking frame_packing; H2645SEIFramePacking frame_packing;
H2645SEIDisplayOrientation display_orientation; H2645SEIDisplayOrientation display_orientation;
H2645SEIAlternativeTransfer alternative_transfer; H2645SEIAlternativeTransfer alternative_transfer;
H2645SEIFilmGrainCharacteristics film_grain_characteristics;
H2645SEIAmbientViewingEnvironment ambient_viewing_environment; H2645SEIAmbientViewingEnvironment ambient_viewing_environment;
H2645SEIMasteringDisplay mastering_display; H2645SEIMasteringDisplay mastering_display;
H2645SEIContentLight content_light; H2645SEIContentLight content_light;
AVFilmGrainAFGS1Params aom_film_grain; AVFilmGrainAFGS1Params aom_film_grain;
// Dynamic allocations due to large size.
H2645SEIFilmGrainCharacteristics *film_grain_characteristics;
} H2645SEI; } H2645SEI;
enum { enum {

View file

@ -55,7 +55,6 @@ void ff_h264_sei_uninit(H264SEIContext *h)
h->picture_timing.present = 0; h->picture_timing.present = 0;
h->buffering_period.present = 0; h->buffering_period.present = 0;
h->common.frame_packing.present = 0; h->common.frame_packing.present = 0;
h->common.film_grain_characteristics.present = 0;
h->common.display_orientation.present = 0; h->common.display_orientation.present = 0;
h->common.afd.present = 0; h->common.afd.present = 0;

View file

@ -516,7 +516,10 @@ static int h264_frame_start(H264Context *h)
pic->f->crop_top = h->crop_top; pic->f->crop_top = h->crop_top;
pic->f->crop_bottom = h->crop_bottom; 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); !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
if ((ret = alloc_picture(h, pic)) < 0) if ((ret = alloc_picture(h, pic)) < 0)

View file

@ -412,7 +412,7 @@ static int export_stream_params_from_sei(HEVCContext *s)
avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics; 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) s->sei.common.aom_film_grain.enable)
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN; avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
@ -3267,7 +3267,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l,
else else
s->cur_frame->f->flags &= ~AV_FRAME_FLAG_KEY; 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->sei.common.aom_film_grain.enable) &&
!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
!s->avctx->hwaccel; !s->avctx->hwaccel;
@ -3277,8 +3278,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l,
goto fail; goto fail;
if (s->cur_frame->needs_fg && if (s->cur_frame->needs_fg &&
(s->sei.common.film_grain_characteristics.present && (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, !ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics->model_id,
s->cur_frame->f->format) || s->cur_frame->f->format) ||
!av_film_grain_params_select(s->cur_frame->f))) { !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, av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown,