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
2222 */
2323 #include "libavcodec/codec_internal.h"
2424 #include "libavcodec/decode.h"
25+#include "libavcodec/hwaccel_internal.h"
26+#include "libavcodec/hwconfig.h"
2527 #include "libavcodec/profiles.h"
2628 #include "libavcodec/refstruct.h"
2729 #include "libavutil/cpu.h"
@@ -606,6 +608,8 @@ static int ref_frame(VVCFrame *dst, const VVCFrame *src) · 578 unmodified lines
606608
607609 ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab);
608610 ff_refstruct_replace(&dst->rpl, src->rpl);
611+ ff_refstruct_replace(&dst->hwaccel_picture_private,
612+ src->hwaccel_picture_private);
609613 dst->nb_rpl_elems = src->nb_rpl_elems;
610614
611615 dst->poc = src->poc;
@@ -766,18 +770,49 @@ static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, · 154 unmodified lines
766770 return 0;
767771 }
768772
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)
770793 {
771794 AVCodecContext *c = s->avctx;
772795 const VVCSPS *sps = fc->ps.sps;
773796 const VVCPPS *pps = fc->ps.pps;
797+ int ret;
774798
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]);
780813 c->has_b_frames = sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1];
814+
815+ return 0;
781816 }
782817
783818 static int frame_setup(VVCFrameContext *fc, VVCContext *s)
@@ -790,8 +825,11 @@ static int frame_setup(VVCFrameContext *fc, VVCContext *s) · 6 unmodified lines
790825 if (ret < 0)
791826 return ret;
792827
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;
795833 }
796834
797835 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
820858 ret = slice_init_entry_points(sc, fc, nal, unit);
821859 if (ret < 0)
822860 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+
823875 fc->nb_slices++;
824876
825877 return 0;
@@ -935,17 +987,26 @@ static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output) · 109 unmodified lines
935987
936988 static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)
937989 {
938− int ret = ff_vvc_frame_submit(s, fc);
990+ int ret;
939991
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+ }
9431004 }
9441005
9451006 s->nb_frames++;
9461007 s->nb_delayed++;
9471008
948− if (s->nb_delayed >= s->nb_fcs) {
1009+ if (s->nb_delayed >= s->nb_fcs || s->avctx->hwaccel) {
9491010 if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
9501011 return ret;
9511012 }
@@ -1091,6 +1152,8 @@ static av_cold int vvc_decode_init(AVCodecContext *avctx) · 139 unmodified lines
10911152 GDR_SET_RECOVERED(s);
10921153 ff_thread_once(&init_static_once, init_default_scale_m);
10931154
1155+ s->pix_fmt = AV_PIX_FMT_NONE;
1156+
10941157 return 0;
10951158 }
10961159
libavcodec/vvc/dec.h+4−0
@@ -101,6 +101,8 @@ typedef struct VVCFrame { · 100 unmodified lines
101101 * A combination of VVC_FRAME_FLAG_*
102102 */
103103 uint8_t flags;
104+
105+ void *hwaccel_picture_private; ///< hardware accelerator private data
104106 } VVCFrame;
105107
106108 typedef struct SliceContext {
@@ -241,6 +243,8 @@ typedef struct VVCContext { · 134 unmodified lines
241243
242244 uint64_t nb_frames; ///< processed frames
243245 int nb_delayed; ///< delayed frames
246+
247+ enum AVPixelFormat pix_fmt; ///< pix format of current frame
244248 } VVCContext ;
245249
246250 #endif /* AVCODEC_VVC_DEC_H */
libavcodec/vvc/refs.c+6−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include "libavutil/thread.h"
2727 #include "libavcodec/refstruct.h"
2828 #include "libavcodec/thread.h"
29+#include "libavcodec/decode.h"
2930
3031 #include "refs.h"
3132
@@ -59,6 +60,7 @@ void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags) · 27 unmodified lines
5960 ff_refstruct_unref(&frame->rpl_tab);
6061
6162 frame->collocated_ref = NULL;
63+ ff_refstruct_unref(&frame->hwaccel_picture_private);
6264 }
6365 }
6466
@@ -153,6 +155,10 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) · 88 unmodified lines
153155 if (!frame->progress)
154156 goto fail;
155157
158+ ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private);
159+ if (ret < 0)
160+ goto fail;
161+
156162 return frame;
157163 fail:
158164 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