History

lavc/vvc_dec: Add hardware decode API

Fei Wang committed 2 years ago

Commit 4dc18c71 parent a94aa2d3 files · +86 −13Browse files

Showing the changes to libavcodec (3 of 3 files). Show all

Unified · Split

3 files
  1. libavcodec/vvc/dec.c +76 −13
  2. libavcodec/vvc/dec.h +4 −0
  3. libavcodec/vvc/refs.c +6 −0
libavcodec/vvc/dec.c+76−13
@@ -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
769static void export_frame_params(VVCContext *s, const VVCFrameContext *fc)773static 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
792static 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
783static int frame_setup(VVCFrameContext *fc, VVCContext *s)818static 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
797static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)835static 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
936static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)988static 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
libavcodec/vvc/dec.h+4−0
@@ -101,6 +101,8 @@ typedef struct VVCFrame { · 100 unmodified lines
101 * A combination of VVC_FRAME_FLAG_*101 * A combination of VVC_FRAME_FLAG_*
102 */102 */
103 uint8_t flags;103 uint8_t flags;
104
105 void *hwaccel_picture_private; ///< hardware accelerator private data
104} VVCFrame;106} VVCFrame;
105 107
106typedef struct SliceContext {108typedef struct SliceContext {
@@ -241,6 +243,8 @@ typedef struct VVCContext { · 134 unmodified lines
241 243
242 uint64_t nb_frames; ///< processed frames244 uint64_t nb_frames; ///< processed frames
243 int nb_delayed; ///< delayed frames245 int nb_delayed; ///< delayed frames
246
247 enum AVPixelFormat pix_fmt; ///< pix format of current frame
244} VVCContext ;248} VVCContext ;
245 249
246#endif /* AVCODEC_VVC_DEC_H */250#endif /* AVCODEC_VVC_DEC_H */
libavcodec/vvc/refs.c+6−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include "libavutil/thread.h"26#include "libavutil/thread.h"
27#include "libavcodec/refstruct.h"27#include "libavcodec/refstruct.h"
28#include "libavcodec/thread.h"28#include "libavcodec/thread.h"
29#include "libavcodec/decode.h"
29 30
30#include "refs.h"31#include "refs.h"
31 32
@@ -59,6 +60,7 @@ void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags) · 27 unmodified lines
59 ff_refstruct_unref(&frame->rpl_tab);60 ff_refstruct_unref(&frame->rpl_tab);
60 61
61 frame->collocated_ref = NULL;62 frame->collocated_ref = NULL;
63 ff_refstruct_unref(&frame->hwaccel_picture_private);
62 }64 }
63}65}
64 66
@@ -153,6 +155,10 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) · 88 unmodified lines
153 if (!frame->progress)155 if (!frame->progress)
154 goto fail;156 goto fail;
155 157
158 ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private);
159 if (ret < 0)
160 goto fail;
161
156 return frame;162 return frame;
157fail:163fail:
158 ff_vvc_unref_frame(fc, frame, ~0);164 ff_vvc_unref_frame(fc, frame, ~0);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t