From: Ovaron Date: Mon, 21 Mar 2022 18:47:08 +0000 (+0100) Subject: Update for VAAPI transcoding X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bf1629280bcd7d33e93df165985f3f6253c4b70;p=thirdparty%2Ftvheadend.git Update for VAAPI transcoding VAAPI: Buffer factor (buffersize manipulation) now configurable at WebUI. VAAPI: Added rc_mode (h264/hevc) and tier (hevc), both configurable via WebUI. VAAPI: Removed B-Frame workaround from the past at HEVC. VAAPI: Added an option for ignore b-frames because some drivers needs this (AMD). VAAPI: Also updated VP8 and VP9 encoding. VAAPI: VP8 and VP9 now also reacts on options for "Buffer factor" and "Ignore B-Frames" and got the "force_key_frames" expression to increase picture quality. VAAPI: Added destroy option for h264 codec (might have created memory issues) --- diff --git a/src/transcoding/codec/codecs/libs/vaapi.c b/src/transcoding/codec/codecs/libs/vaapi.c index 6c18d596c..cbcfe9b47 100644 --- a/src/transcoding/codec/codecs/libs/vaapi.c +++ b/src/transcoding/codec/codecs/libs/vaapi.c @@ -33,6 +33,10 @@ typedef struct { TVHVideoCodecProfile; int qp; int quality; + double buff_factor; + int rc_mode; + int tier; + int ignore_bframe; } tvh_codec_profile_vaapi_t; #if defined(__linux__) @@ -142,6 +146,27 @@ static const codec_profile_class_t codec_profile_vaapi_class = { .off = offsetof(TVHCodecProfile, bit_rate), .def.d = 0, }, + { + .type = PT_DBL, + .id = "buff_factor", + .name = N_("Buffer factor"), + .desc = N_("Size of transcoding buffer (buffer=bitrate*1000*factor). Good factor is 3."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, buff_factor), + .def.d = 3, + }, + { + .type = PT_INT, + .id = "rc_mode", + .name = N_("Rate control mode"), + .desc = N_("Set rate control mode (from 0 to 6).[0=auto 1=CQP 2=CBR 3=VBR 4=ICQ 5=QVBR 6=AVBR]"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, rc_mode), + .intextra = INTEXTRA_RANGE(0, 6, 0), + .def.d = 0, + }, { .type = PT_INT, .id = "qp", @@ -153,6 +178,17 @@ static const codec_profile_class_t codec_profile_vaapi_class = { .intextra = INTEXTRA_RANGE(0, 52, 1), .def.i = 0, }, + { + .type = PT_INT, + .id = "ignore_bframe", + .name = N_("Ignore B-Frames"), + .group = 3, + .desc = N_("Some VAAPI drivers cannot handle b-frames (like AMD). [0=use b-frames (default) 1=ignore b-frames]"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, ignore_bframe), + .intextra = INTEXTRA_RANGE(0, 1, 0), + .def.i = 0, + }, {} } }, @@ -175,10 +211,17 @@ tvh_codec_profile_vaapi_h264_open(tvh_codec_profile_vaapi_t *self, { // bit_rate or qp if (self->bit_rate) { + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } AV_DICT_SET_BIT_RATE(opts, self->bit_rate); AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * 3, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * self->buff_factor, AV_DICT_DONT_OVERWRITE); AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + if (self->ignore_bframe) { + AV_DICT_SET_INT(opts, "bf", 0, 0); + } } else { AV_DICT_SET_QP(opts, self->qp, 20); @@ -219,6 +262,8 @@ TVHVideoCodec tvh_codec_vaapi_h264 = { .size = sizeof(tvh_codec_profile_vaapi_t), .idclass = &codec_profile_vaapi_h264_class, .profiles = vaapi_h264_profiles, + .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; @@ -238,17 +283,21 @@ tvh_codec_profile_vaapi_hevc_open(tvh_codec_profile_vaapi_t *self, // bit_rate or qp if (self->bit_rate) { AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * 3, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * self->buff_factor, AV_DICT_DONT_OVERWRITE); AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); + if (self->ignore_bframe) { + AV_DICT_SET_INT(opts, "bf", 0, 0); + } } else { AV_DICT_SET_QP(opts, self->qp, 25); } - // max_b_frames - // XXX: remove when b-frames handling in vaapi_encode is fixed - AV_DICT_SET_INT(opts, "bf", 0, 0); - return 0; } @@ -257,7 +306,22 @@ static const codec_profile_class_t codec_profile_vaapi_hevc_class = { { .ic_super = (idclass_t *)&codec_profile_vaapi_class, .ic_class = "codec_profile_vaapi_hevc", - .ic_caption = N_("vaapi_hevc") + .ic_caption = N_("vaapi_hevc"), + .ic_properties = (const property_t[]){ + { + .type = PT_INT, + .id = "tier", + .name = N_("Tier"), + .desc = N_("Set tier (general_tier_flag) [0=main 1=high]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, tier), + .intextra = INTEXTRA_RANGE(0, 1, 0), + .def.i = 0, + }, + {} + } }, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_hevc_open, }; @@ -286,12 +350,19 @@ tvh_codec_profile_vaapi_vp8_open(tvh_codec_profile_vaapi_t *self, // bit_rate or qp if (self->bit_rate) { AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * self->buff_factor, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); } else { AV_DICT_SET_QP(opts, self->qp, 25); } - // force zero here, until encoder is fixed - AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->ignore_bframe) { + AV_DICT_SET_INT(opts, "bf", 0, 0); + } return 0; } @@ -328,12 +399,19 @@ tvh_codec_profile_vaapi_vp9_open(tvh_codec_profile_vaapi_t *self, // bit_rate or qp if (self->bit_rate) { AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + AV_DICT_SET_INT(opts, "maxrate", (self->bit_rate) * 1000, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", ((self->bit_rate) * 1000) * self->buff_factor, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); } else { AV_DICT_SET_QP(opts, self->qp, 25); } - // force zero here, until encoder is fixed - AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->ignore_bframe) { + AV_DICT_SET_INT(opts, "bf", 0, 0); + } return 0; }