| @@ -22,6 +22,8 @@ · 21 unmodified lines |
| 22 | 22 | */ |
| 23 | 23 | #include "libavcodec/codec_internal.h" |
| 24 | 24 | #include "libavcodec/decode.h" |
| 25 | +#include "libavcodec/hwaccel_internal.h" |
| 26 | +#include "libavcodec/hwconfig.h" |
| 25 | 27 | #include "libavcodec/profiles.h" |
| 26 | 28 | #include "libavcodec/refstruct.h" |
| 27 | 29 | #include "libavutil/cpu.h" |
| @@ -606,6 +608,8 @@ static int ref_frame(VVCFrame *dst, const VVCFrame *src) · 578 unmodified lines |
| 606 | 608 | |
| 607 | 609 | ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab); |
| 608 | 610 | ff_refstruct_replace(&dst->rpl, src->rpl); |
| 611 | + ff_refstruct_replace(&dst->hwaccel_picture_private, |
| 612 | + src->hwaccel_picture_private); |
| 609 | 613 | dst->nb_rpl_elems = src->nb_rpl_elems; |
| 610 | 614 | |
| 611 | 615 | dst->poc = src->poc; |
| @@ -766,18 +770,49 @@ static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, · 154 unmodified lines |
| 766 | 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 | 794 | AVCodecContext *c = s->avctx; |
| 772 | 795 | const VVCSPS *sps = fc->ps.sps; |
| 773 | 796 | const VVCPPS *pps = fc->ps.pps; |
| 797 | + int ret; |
| 774 | 798 | |
| 775 | | − c->pix_fmt = sps->pix_fmt; |
| 776 | | − c->coded_width = pps->width; |
| 777 | | − c->coded_height = pps->height; |
| 778 | | − c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]); |
| 779 | | − c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]); |
| 799 | + // Reset HW config if pix_fmt/w/h change. |
| 800 | + if (s->pix_fmt != sps->pix_fmt || c->coded_width != pps->width || c->coded_height != pps->height) { |
| 801 | + c->coded_width = pps->width; |
| 802 | + c->coded_height = pps->height; |
| 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 | 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 | 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 | 825 | if (ret < 0) |
| 791 | 826 | return ret; |
| 792 | 827 | |
| 793 | | − export_frame_params(s, fc); |
| 794 | | − return ret; |
| 828 | + ret = export_frame_params(s, fc); |
| 829 | + if (ret < 0) |
| 830 | + return ret; |
| 831 | + |
| 832 | + return 0; |
| 795 | 833 | } |
| 796 | 834 | |
| 797 | 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 | 858 | ret = slice_init_entry_points(sc, fc, nal, unit); |
| 821 | 859 | if (ret < 0) |
| 822 | 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 | 875 | fc->nb_slices++; |
| 824 | 876 | |
| 825 | 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 | 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) { |
| 941 | | − ff_vvc_report_frame_finished(fc->ref); |
| 942 | | − return ret; |
| 992 | + if (s->avctx->hwaccel) { |
| 993 | + if (ret = FF_HW_SIMPLE_CALL(s->avctx, end_frame) < 0) { |
| 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 | 1006 | s->nb_frames++; |
| 946 | 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 | 1010 | if ((ret = wait_delayed_frame(s, output, got_output)) < 0) |
| 950 | 1011 | return ret; |
| 951 | 1012 | } |
| @@ -1091,6 +1152,8 @@ static av_cold int vvc_decode_init(AVCodecContext *avctx) · 139 unmodified lines |
| 1091 | 1152 | GDR_SET_RECOVERED(s); |
| 1092 | 1153 | ff_thread_once(&init_static_once, init_default_scale_m); |
| 1093 | 1154 | |
| 1155 | + s->pix_fmt = AV_PIX_FMT_NONE; |
| 1156 | + |
| 1094 | 1157 | return 0; |
| 1095 | 1158 | } |
| 1096 | 1159 | |