diff options
author | Niklas Haas <git@haasn.dev> | 2021-09-29 01:06:02 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2021-10-15 11:55:45 -0300 |
commit | 3cc3f5de2afda5b8f880c0817e9d67c2dafbfe1e (patch) | |
tree | b6b31494a972106f66ebb8219bfce5fbed40ceb9 /libavcodec/hevc_refs.c | |
parent | 5d16660598dd9409c1028204cac3a966a939b719 (diff) | |
download | ffmpeg-3cc3f5de2afda5b8f880c0817e9d67c2dafbfe1e.tar.gz |
avcodec/hevcdec: apply H.274 film grain
Similar in spirit and design to 66845cffc3bbb, but slightly simpler due
to the lack of interlaced frames in HEVC. See that commit for more
details.
For the seed value, since no specification for this appears to exist, I
semi-arbitrarily decided to base it off the POC id alone, since there's
no analog of the idr_pic_id in HEVC's I-frames. This design is stable
across remuxes and seeks, but changes for adjacent frames with a period
that's typically long enough not to be noticeable, which makes it
satisfy all of the requirements that a film grain seed should have.
Tested with and without threading, using a patch to insert film grain
metadata artificially (for lack of real files containing film grain).
Diffstat (limited to 'libavcodec/hevc_refs.c')
-rw-r--r-- | libavcodec/hevc_refs.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 4f6d985ae6..06e42d9c53 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -38,6 +38,8 @@ void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags) frame->flags &= ~flags; if (!frame->flags) { ff_thread_release_buffer(s->avctx, &frame->tf); + ff_thread_release_buffer(s->avctx, &frame->tf_grain); + frame->needs_fg = 0; av_buffer_unref(&frame->tab_mvf_buf); frame->tab_mvf = NULL; @@ -208,7 +210,7 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) if (nb_output) { HEVCFrame *frame = &s->DPB[min_idx]; - ret = av_frame_ref(out, frame->frame); + ret = av_frame_ref(out, frame->needs_fg ? frame->frame_grain : frame->frame); if (frame->flags & HEVC_FRAME_FLAG_BUMPING) ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); else @@ -216,6 +218,12 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) if (ret < 0) return ret; + if (frame->needs_fg && (ret = av_frame_copy_props(out, frame->frame)) < 0) + return ret; + + if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) + av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS); + av_log(s->avctx, AV_LOG_DEBUG, "Output frame with POC %d.\n", frame->poc); return 1; |