| @@ -22,6 +22,8 @@ · 21 unmodified lines |
| 22 | */ | 22 | */ |
| 23 | #include "libavcodec/codec_internal.h" | 23 | #include "libavcodec/codec_internal.h" |
| 24 | #include "libavcodec/decode.h" | 24 | #include "libavcodec/decode.h" |
| | 25 | #include "libavcodec/hwaccel_internal.h" |
| | 26 | #include "libavcodec/hwconfig.h" |
| 25 | #include "libavcodec/profiles.h" | 27 | #include "libavcodec/profiles.h" |
| 26 | #include "libavcodec/refstruct.h" | 28 | #include "libavcodec/refstruct.h" |
| 27 | #include "libavutil/cpu.h" | 29 | #include "libavutil/cpu.h" |
| @@ -606,6 +608,8 @@ static int ref_frame(VVCFrame *dst, const VVCFrame *src) · 578 unmodified lines |
| 606 | | 608 | |
| 607 | ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab); | 609 | ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab); |
| 608 | ff_refstruct_replace(&dst->rpl, src->rpl); | 610 | ff_refstruct_replace(&dst->rpl, src->rpl); |
| | 611 | ff_refstruct_replace(&dst->hwaccel_picture_private, |
| | 612 | src->hwaccel_picture_private); |
| 609 | dst->nb_rpl_elems = src->nb_rpl_elems; | 613 | dst->nb_rpl_elems = src->nb_rpl_elems; |
| 610 | | 614 | |
| 611 | dst->poc = src->poc; | 615 | dst->poc = src->poc; |
| @@ -766,18 +770,49 @@ static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, · 154 unmodified lines |
| 766 | return 0; | 770 | return 0; |
| 767 | } | 771 | } |
| 768 | | 772 | |
| 769 | static void export_frame_params(VVCContext *s, const VVCFrameContext *fc) | 773 | static enum AVPixelFormat get_format(AVCodecContext *avctx, const VVCSPS *sps) |
| | 774 | { |
| | 775 | #define HWACCEL_MAX 0 |
| | 776 | |
| | 777 | enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; |
| | 778 | |
| | 779 | switch (sps->pix_fmt) { |
| | 780 | case AV_PIX_FMT_YUV420P: |
| | 781 | break; |
| | 782 | case AV_PIX_FMT_YUV420P10: |
| | 783 | break; |
| | 784 | } |
| | 785 | |
| | 786 | *fmt++ = sps->pix_fmt; |
| | 787 | *fmt = AV_PIX_FMT_NONE; |
| | 788 | |
| | 789 | return ff_get_format(avctx, pix_fmts); |
| | 790 | } |
| | 791 | |
| | 792 | static int export_frame_params(VVCContext *s, const VVCFrameContext *fc) |
| 770 | { | 793 | { |
| 771 | AVCodecContext *c = s->avctx; | 794 | AVCodecContext *c = s->avctx; |
| 772 | const VVCSPS *sps = fc->ps.sps; | 795 | const VVCSPS *sps = fc->ps.sps; |
| 773 | const VVCPPS *pps = fc->ps.pps; | 796 | const VVCPPS *pps = fc->ps.pps; |
| | 797 | int ret; |
| 774 | | 798 | |
| 775 | c->pix_fmt = sps->pix_fmt; | 799 | // Reset HW config if pix_fmt/w/h change. |
| 776 | c->coded_width = pps->width; | 800 | if (s->pix_fmt != sps->pix_fmt || c->coded_width != pps->width || c->coded_height != pps->height) { |
| 777 | c->coded_height = pps->height; | 801 | c->coded_width = pps->width; |
| 778 | c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]); | 802 | c->coded_height = pps->height; |
| 779 | c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]); | 803 | ret = get_format(c, sps); |
| | 804 | if (ret < 0) |
| | 805 | return ret; |
| | 806 | |
| | 807 | c->pix_fmt = ret; |
| | 808 | s->pix_fmt = sps->pix_fmt; |
| | 809 | } |
| | 810 | |
| | 811 | c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]); |
| | 812 | c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]); |
| 780 | c->has_b_frames = sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1]; | 813 | c->has_b_frames = sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1]; |
| | 814 | |
| | 815 | return 0; |
| 781 | } | 816 | } |
| 782 | | 817 | |
| 783 | static int frame_setup(VVCFrameContext *fc, VVCContext *s) | 818 | static int frame_setup(VVCFrameContext *fc, VVCContext *s) |
| @@ -790,8 +825,11 @@ static int frame_setup(VVCFrameContext *fc, VVCContext *s) · 6 unmodified lines |
| 790 | if (ret < 0) | 825 | if (ret < 0) |
| 791 | return ret; | 826 | return ret; |
| 792 | | 827 | |
| 793 | export_frame_params(s, fc); | 828 | ret = export_frame_params(s, fc); |
| 794 | return ret; | 829 | if (ret < 0) |
| | 830 | return ret; |
| | 831 | |
| | 832 | return 0; |
| 795 | } | 833 | } |
| 796 | | 834 | |
| 797 | static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit) | 835 | static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit) |
| @@ -820,6 +858,20 @@ static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, · 22 unmodified lines |
| 820 | ret = slice_init_entry_points(sc, fc, nal, unit); | 858 | ret = slice_init_entry_points(sc, fc, nal, unit); |
| 821 | if (ret < 0) | 859 | if (ret < 0) |
| 822 | return ret; | 860 | return ret; |
| | 861 | |
| | 862 | if (s->avctx->hwaccel) { |
| | 863 | if (is_first_slice) { |
| | 864 | ret = FF_HW_CALL(s->avctx, start_frame, NULL, 0); |
| | 865 | if (ret < 0) |
| | 866 | return ret; |
| | 867 | } |
| | 868 | |
| | 869 | ret = FF_HW_CALL(s->avctx, decode_slice, |
| | 870 | nal->raw_data, nal->raw_size); |
| | 871 | if (ret < 0) |
| | 872 | return ret; |
| | 873 | } |
| | 874 | |
| 823 | fc->nb_slices++; | 875 | fc->nb_slices++; |
| 824 | | 876 | |
| 825 | return 0; | 877 | return 0; |
| @@ -935,17 +987,26 @@ static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output) · 109 unmodified lines |
| 935 | | 987 | |
| 936 | static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output) | 988 | static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output) |
| 937 | { | 989 | { |
| 938 | int ret = ff_vvc_frame_submit(s, fc); | 990 | int ret; |
| 939 | | 991 | |
| 940 | if (ret < 0) { | 992 | if (s->avctx->hwaccel) { |
| 941 | ff_vvc_report_frame_finished(fc->ref); | 993 | if (ret = FF_HW_SIMPLE_CALL(s->avctx, end_frame) < 0) { |
| 942 | return ret; | 994 | av_log(s->avctx, AV_LOG_ERROR, |
| | 995 | "Hardware accelerator failed to decode picture\n"); |
| | 996 | ff_vvc_unref_frame(fc, fc->ref, ~0); |
| | 997 | return ret; |
| | 998 | } |
| | 999 | } else { |
| | 1000 | if (ret = ff_vvc_frame_submit(s, fc) < 0) { |
| | 1001 | ff_vvc_report_frame_finished(fc->ref); |
| | 1002 | return ret; |
| | 1003 | } |
| 943 | } | 1004 | } |
| 944 | | 1005 | |
| 945 | s->nb_frames++; | 1006 | s->nb_frames++; |
| 946 | s->nb_delayed++; | 1007 | s->nb_delayed++; |
| 947 | | 1008 | |
| 948 | if (s->nb_delayed >= s->nb_fcs) { | 1009 | if (s->nb_delayed >= s->nb_fcs || s->avctx->hwaccel) { |
| 949 | if ((ret = wait_delayed_frame(s, output, got_output)) < 0) | 1010 | if ((ret = wait_delayed_frame(s, output, got_output)) < 0) |
| 950 | return ret; | 1011 | return ret; |
| 951 | } | 1012 | } |
| @@ -1091,6 +1152,8 @@ static av_cold int vvc_decode_init(AVCodecContext *avctx) · 139 unmodified lines |
| 1091 | GDR_SET_RECOVERED(s); | 1152 | GDR_SET_RECOVERED(s); |
| 1092 | ff_thread_once(&init_static_once, init_default_scale_m); | 1153 | ff_thread_once(&init_static_once, init_default_scale_m); |
| 1093 | | 1154 | |
| | 1155 | s->pix_fmt = AV_PIX_FMT_NONE; |
| | 1156 | |
| 1094 | return 0; | 1157 | return 0; |
| 1095 | } | 1158 | } |
| 1096 | | 1159 | |