| @@ -26,9 +26,12 @@ · 25 unmodified lines |
| 26 | #include "libavcodec/hwconfig.h" | 26 | #include "libavcodec/hwconfig.h" |
| 27 | #include "libavcodec/profiles.h" | 27 | #include "libavcodec/profiles.h" |
| 28 | #include "libavutil/refstruct.h" | 28 | #include "libavutil/refstruct.h" |
| | 29 | #include "libavcodec/aom_film_grain.h" |
| | 30 | #include "libavcodec/thread.h" |
| 29 | #include "libavutil/cpu.h" | 31 | #include "libavutil/cpu.h" |
| 30 | #include "libavutil/mem.h" | 32 | #include "libavutil/mem.h" |
| 31 | #include "libavutil/thread.h" | 33 | #include "libavutil/thread.h" |
| | 34 | #include "libavutil/film_grain_params.h" |
| 32 | | 35 | |
| 33 | #include "dec.h" | 36 | #include "dec.h" |
| 34 | #include "ctu.h" | 37 | #include "ctu.h" |
| @@ -618,6 +621,14 @@ static int ref_frame(VVCFrame *dst, const VVCFrame *src) · 583 unmodified lines |
| 618 | av_refstruct_replace(&dst->sps, src->sps); | 621 | av_refstruct_replace(&dst->sps, src->sps); |
| 619 | av_refstruct_replace(&dst->pps, src->pps); | 622 | av_refstruct_replace(&dst->pps, src->pps); |
| 620 | | 623 | |
| | 624 | if (src->needs_fg) { |
| | 625 | ret = av_frame_ref(dst->frame_grain, src->frame_grain); |
| | 626 | if (ret < 0) |
| | 627 | return ret; |
| | 628 | |
| | 629 | dst->needs_fg = src->needs_fg; |
| | 630 | } |
| | 631 | |
| 621 | av_refstruct_replace(&dst->progress, src->progress); | 632 | av_refstruct_replace(&dst->progress, src->progress); |
| 622 | | 633 | |
| 623 | av_refstruct_replace(&dst->tab_dmvr_mvf, src->tab_dmvr_mvf); | 634 | av_refstruct_replace(&dst->tab_dmvr_mvf, src->tab_dmvr_mvf); |
| @@ -651,6 +662,7 @@ static av_cold void frame_context_free(VVCFrameContext *fc) · 27 unmodified lines |
| 651 | for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { | 662 | for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) { |
| 652 | ff_vvc_unref_frame(fc, &fc->DPB[i], ~0); | 663 | ff_vvc_unref_frame(fc, &fc->DPB[i], ~0); |
| 653 | av_frame_free(&fc->DPB[i].frame); | 664 | av_frame_free(&fc->DPB[i].frame); |
| | 665 | av_frame_free(&fc->DPB[i].frame_grain); |
| 654 | } | 666 | } |
| 655 | | 667 | |
| 656 | ff_vvc_frame_thread_free(fc); | 668 | ff_vvc_frame_thread_free(fc); |
| @@ -673,6 +685,10 @@ static av_cold int frame_context_init(VVCFrameContext *fc, AVCodecContext *avctx · 16 unmodified lines |
| 673 | fc->DPB[j].frame = av_frame_alloc(); | 685 | fc->DPB[j].frame = av_frame_alloc(); |
| 674 | if (!fc->DPB[j].frame) | 686 | if (!fc->DPB[j].frame) |
| 675 | return AVERROR(ENOMEM); | 687 | return AVERROR(ENOMEM); |
| | 688 | |
| | 689 | fc->DPB[j].frame_grain = av_frame_alloc(); |
| | 690 | if (!fc->DPB[j].frame_grain) |
| | 691 | return AVERROR(ENOMEM); |
| 676 | } | 692 | } |
| 677 | fc->cu_pool = av_refstruct_pool_alloc(sizeof(CodingUnit), 0); | 693 | fc->cu_pool = av_refstruct_pool_alloc(sizeof(CodingUnit), 0); |
| 678 | if (!fc->cu_pool) | 694 | if (!fc->cu_pool) |
| @@ -743,6 +759,41 @@ static int set_side_data(VVCContext *s, VVCFrameContext *fc) · 64 unmodified lines |
| 743 | NULL, fc->ps.sps->bit_depth, fc->ps.sps->bit_depth, fc->ref->poc); | 759 | NULL, fc->ps.sps->bit_depth, fc->ps.sps->bit_depth, fc->ref->poc); |
| 744 | } | 760 | } |
| 745 | | 761 | |
| | 762 | static int check_film_grain(VVCContext *s, VVCFrameContext *fc) |
| | 763 | { |
| | 764 | int ret; |
| | 765 | |
| | 766 | fc->ref->needs_fg = (fc->sei.common.film_grain_characteristics && |
| | 767 | fc->sei.common.film_grain_characteristics->present || |
| | 768 | fc->sei.common.aom_film_grain.enable) && |
| | 769 | !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && |
| | 770 | !s->avctx->hwaccel; |
| | 771 | |
| | 772 | if (fc->ref->needs_fg && |
| | 773 | (fc->sei.common.film_grain_characteristics->present && |
| | 774 | !ff_h274_film_grain_params_supported(fc->sei.common.film_grain_characteristics->model_id, |
| | 775 | fc->ref->frame->format) || |
| | 776 | !av_film_grain_params_select(fc->ref->frame))) { |
| | 777 | av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown, |
| | 778 | "Unsupported film grain parameters. Ignoring film grain.\n"); |
| | 779 | fc->ref->needs_fg = 0; |
| | 780 | } |
| | 781 | |
| | 782 | if (fc->ref->needs_fg) { |
| | 783 | fc->ref->frame_grain->format = fc->ref->frame->format; |
| | 784 | fc->ref->frame_grain->width = fc->ref->frame->width; |
| | 785 | fc->ref->frame_grain->height = fc->ref->frame->height; |
| | 786 | |
| | 787 | ret = ff_thread_get_buffer(s->avctx, fc->ref->frame_grain, 0); |
| | 788 | if (ret < 0) |
| | 789 | return ret; |
| | 790 | |
| | 791 | return av_frame_copy_props(fc->ref->frame_grain, fc->ref->frame); |
| | 792 | } |
| | 793 | |
| | 794 | return 0; |
| | 795 | } |
| | 796 | |
| 746 | static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) | 797 | static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) |
| 747 | { | 798 | { |
| 748 | const VVCPH *ph = &fc->ps.ph; | 799 | const VVCPH *ph = &fc->ps.ph; |
| @@ -762,6 +813,10 @@ static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) · 13 unmodified lines |
| 762 | if (ret < 0) | 813 | if (ret < 0) |
| 763 | goto fail; | 814 | goto fail; |
| 764 | | 815 | |
| | 816 | ret = check_film_grain(s, fc); |
| | 817 | if (ret < 0) |
| | 818 | goto fail; |
| | 819 | |
| 765 | if (!IS_IDR(s)) | 820 | if (!IS_IDR(s)) |
| 766 | ff_vvc_bump_frame(s, fc); | 821 | ff_vvc_bump_frame(s, fc); |
| 767 | | 822 | |
| @@ -1019,14 +1074,42 @@ fail: · 251 unmodified lines |
| 1019 | return ret; | 1074 | return ret; |
| 1020 | } | 1075 | } |
| 1021 | | 1076 | |
| | 1077 | static int frame_end(VVCContext *s, VVCFrameContext *fc) |
| | 1078 | { |
| | 1079 | const AVFilmGrainParams *fgp; |
| | 1080 | int ret = 0; |
| | 1081 | |
| | 1082 | if (fc->ref->needs_fg) { |
| | 1083 | av_assert0(fc->ref->frame_grain->buf[0]); |
| | 1084 | fgp = av_film_grain_params_select(fc->ref->frame); |
| | 1085 | switch (fgp->type) { |
| | 1086 | case AV_FILM_GRAIN_PARAMS_NONE: |
| | 1087 | av_assert0(0); |
| | 1088 | return AVERROR_BUG; |
| | 1089 | case AV_FILM_GRAIN_PARAMS_H274: |
| | 1090 | ret = ff_h274_apply_film_grain(fc->ref->frame_grain, fc->ref->frame, |
| | 1091 | &s->h274db, fgp); |
| | 1092 | break; |
| | 1093 | case AV_FILM_GRAIN_PARAMS_AV1: |
| | 1094 | ret = ff_aom_apply_film_grain(fc->ref->frame_grain, fc->ref->frame, fgp); |
| | 1095 | break; |
| | 1096 | } |
| | 1097 | } |
| | 1098 | |
| | 1099 | return ret; |
| | 1100 | } |
| | 1101 | |
| 1022 | static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output) | 1102 | static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output) |
| 1023 | { | 1103 | { |
| 1024 | VVCFrameContext *delayed = get_frame_context(s, s->fcs, s->nb_frames - s->nb_delayed); | 1104 | VVCFrameContext *delayed = get_frame_context(s, s->fcs, s->nb_frames - s->nb_delayed); |
| 1025 | int ret = ff_vvc_frame_wait(s, delayed); | 1105 | int ret = ff_vvc_frame_wait(s, delayed); |
| 1026 | | 1106 | |
| 1027 | if (!ret && delayed->output_frame->buf[0] && output) { | 1107 | if (!ret) { |
| 1028 | av_frame_move_ref(output, delayed->output_frame); | 1108 | ret = frame_end(s, delayed); |
| 1029 | *got_output = 1; | 1109 | if (ret >= 0 && delayed->output_frame->buf[0] && output) { |
| | 1110 | av_frame_move_ref(output, delayed->output_frame); |
| | 1111 | *got_output = 1; |
| | 1112 | } |
| 1030 | } | 1113 | } |
| 1031 | s->nb_delayed--; | 1114 | s->nb_delayed--; |
| 1032 | | 1115 | |