From: Ukn Unknown <4031821+uknunknown@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:39:02 +0000 (-0800) Subject: allow NVENC, VAAPI and MMAL to coexist in the same build X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=cf29292592756f778024b3f5d8df166dad899285;p=thirdparty%2Ftvheadend.git allow NVENC, VAAPI and MMAL to coexist in the same build - allow NVENC, VAAPI and MMAL to coexist in the same build. - give the user the capability for prioritize hw decoder or to match the hw decoder with hw encoder - refactor source code: remove duplicate source code in codec.js --- diff --git a/src/transcoding/codec.h b/src/transcoding/codec.h index 43b708462..f5b5fde78 100644 --- a/src/transcoding/codec.h +++ b/src/transcoding/codec.h @@ -136,6 +136,9 @@ tvh_codec_profile_video_destroy(TVHCodecProfile *_self); int tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self); +int +tvh_codec_profile_video_get_hwaccel_details(TVHCodecProfile *self); + const enum AVPixelFormat * tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self); diff --git a/src/transcoding/codec/internals.h b/src/transcoding/codec/internals.h index db88d575b..7b8799f12 100644 --- a/src/transcoding/codec/internals.h +++ b/src/transcoding/codec/internals.h @@ -119,6 +119,16 @@ AV_DICT_SET_INT((d), "pix_fmt", ((v) != AV_PIX_FMT_NONE) ? (v) : (a), \ AV_DICT_DONT_OVERWRITE) +#define HWACCEL_AUTO 0 +#if ENABLE_VAAPI +#define HWACCEL_PRIORITIZE_VAAPI 1 +#endif +#if ENABLE_NVENC +#define HWACCEL_PRIORITIZE_NVDEC 2 +#endif +#if ENABLE_MMAL +#define HWACCEL_PRIORITIZE_MMAL 3 +#endif /* codec_profile_class ====================================================== */ @@ -221,6 +231,7 @@ typedef struct tvh_codec_profile_video { int height; int scaling_mode; // 0 --> up&down; 1 --> up; 2 --> down int hwaccel; + int hwaccel_details; int pix_fmt; int crf; AVRational size; diff --git a/src/transcoding/codec/profile.c b/src/transcoding/codec/profile.c index 12796f3cf..2e1dff444 100644 --- a/src/transcoding/codec/profile.c +++ b/src/transcoding/codec/profile.c @@ -286,6 +286,18 @@ tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self) return -1; } + +int +tvh_codec_profile_video_get_hwaccel_details(TVHCodecProfile *self) +{ + TVHCodec *codec = tvh_codec_profile_get_codec(self); + if (codec && tvh_codec_is_enabled(codec) && + tvh_codec_get_type(codec) == AVMEDIA_TYPE_VIDEO) { + return ((TVHVideoCodecProfile *)self)->hwaccel_details; + } + return -1; +} + const enum AVPixelFormat * tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self) { diff --git a/src/transcoding/codec/profile_video_class.c b/src/transcoding/codec/profile_video_class.c index 00bfbbf99..07a392fa8 100644 --- a/src/transcoding/codec/profile_video_class.c +++ b/src/transcoding/codec/profile_video_class.c @@ -33,6 +33,25 @@ scaling_mode_get_list( void *o, const char *lang ) return strtab2htsmsg(tab, 1, lang); } +static htsmsg_t * +hwaccel_get_list( void *o, const char *lang ) +{ + static const struct strtab tab[] = { + { N_("auto (recommended)"), HWACCEL_AUTO}, +#if ENABLE_VAAPI + { N_("prioritize VAAPI"), HWACCEL_PRIORITIZE_VAAPI}, +#endif +#if ENABLE_NVENC + { N_("prioritize NVDEC"), HWACCEL_PRIORITIZE_NVDEC}, +#endif +#if ENABLE_MMAL + { N_("prioritize MMAL"), HWACCEL_PRIORITIZE_MMAL}, +#endif + }; + return strtab2htsmsg(tab, 1, lang); +} + + /* TVHCodec ================================================================= */ static htsmsg_t * @@ -215,6 +234,16 @@ const codec_profile_class_t codec_profile_video_class = { .off = offsetof(TVHVideoCodecProfile, hwaccel), .def.i = 0, }, + { + .type = PT_INT, + .id = "hwaccel_details", + .name = N_("Hardware acceleration details"), + .desc = N_("Force hardware acceleration."), + .group = 2, + .off = offsetof(TVHVideoCodecProfile, hwaccel_details), + .list = hwaccel_get_list, + .def.i = 0, + }, { .type = PT_INT, .id = "pix_fmt", diff --git a/src/transcoding/transcode/stream.c b/src/transcoding/transcode/stream.c index b3117e3bc..0589d62e8 100644 --- a/src/transcoding/transcode/stream.c +++ b/src/transcoding/transcode/stream.c @@ -57,16 +57,26 @@ tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc) { enum AVCodecID icodec_id = streaming_component_type2codec_id(ssc->es_type); const AVCodec *icodec = NULL, *ocodec = NULL; + int hwaccel = -1; + int hwaccel_details = -1; if (icodec_id == AV_CODEC_ID_NONE) { tvh_stream_log(self, LOG_ERR, "unknown decoder id for '%s'", streaming_component_type2txt(ssc->es_type)); return -1; } + if ((hwaccel = tvh_codec_profile_video_get_hwaccel(profile)) < 0) { + return -1; + } + if ((hwaccel_details = tvh_codec_profile_video_get_hwaccel_details(profile)) < 0) { + return -1; + } #if ENABLE_MMAL if (idnode_is_instance(&profile->idnode, (idclass_t *)&codec_profile_video_class)) { - if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { + if (hwaccel && + ((hwaccel_details == HWACCEL_AUTO && strstr(profile->codec_name, "mmal")) || + hwaccel_details == HWACCEL_PRIORITIZE_MMAL)) { if (icodec_id == AV_CODEC_ID_H264) { icodec = avcodec_find_decoder_by_name("h264_mmal"); } else if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) { @@ -76,9 +86,12 @@ tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc) } #endif #if ENABLE_NVENC - if (idnode_is_instance(&profile->idnode, + if (!icodec && idnode_is_instance(&profile->idnode, (idclass_t *)&codec_profile_video_class)) { - if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { + if (hwaccel && + ((hwaccel_details == HWACCEL_AUTO && strstr(profile->codec_name, "nvenc")) || + hwaccel_details == HWACCEL_PRIORITIZE_NVDEC)) { + // https://developer.nvidia.com/video-codec-sdk if (icodec_id == AV_CODEC_ID_H264) { icodec = avcodec_find_decoder_by_name("h264_cuvid"); } else if (icodec_id == AV_CODEC_ID_HEVC) { @@ -86,6 +99,27 @@ tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc) } } } +#endif +#if ENABLE_VAAPI + if (!icodec && idnode_is_instance(&profile->idnode, + (idclass_t *)&codec_profile_video_class)) { + if (hwaccel && + (hwaccel_details == HWACCEL_PRIORITIZE_VAAPI)) { + if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) { + icodec = avcodec_find_decoder_by_name("mpeg2_vaapi"); + } else if (icodec_id == AV_CODEC_ID_H264) { + icodec = avcodec_find_decoder_by_name("h264_vaapi"); + } else if (icodec_id == AV_CODEC_ID_HEVC) { + icodec = avcodec_find_decoder_by_name("hevc_vaapi"); + } else if (icodec_id == AV_CODEC_ID_VP9) { + icodec = avcodec_find_decoder_by_name("vp9_vaapi"); + } else if (icodec_id == AV_CODEC_ID_VP8) { + icodec = avcodec_find_decoder_by_name("vp8_vaapi"); + }else if (icodec_id == AV_CODEC_ID_MJPEG) { + icodec = avcodec_find_decoder_by_name("mjpeg_vaapi"); + } + } + } #endif if (!icodec && !(icodec = avcodec_find_decoder(icodec_id))) { tvh_stream_log(self, LOG_ERR, "failed to find decoder for '%s'", diff --git a/src/webui/static/app/codec.js b/src/webui/static/app/codec.js index c791f353a..014494224 100644 --- a/src/webui/static/app/codec.js +++ b/src/webui/static/app/codec.js @@ -24,6 +24,232 @@ function genericCBRvsVBR(form) { }); } +// functions used for Video Codec profiles + +function update_hwaccel_details(form) { + form.findField('hwaccel_details').setDisabled(!form.findField('hwaccel').getValue()); +} + +function enable_hwaccels_details(form) { + if (form.findField('hwaccel_details') && form.findField('hwaccel')) { + update_hwaccel_details(form); + // on hwaccel change + form.findField('hwaccel').on('check', function(checkbox, value) { + update_hwaccel_details(form); + }); + } +} + +// functions used for VAAPI Video Codec profiles + +function updateHWFilters(form) { + if (form.findField('hw_denoise') && form.findField('hw_sharpness') && + form.findField('hwaccel_details') && form.findField('hwaccel')) + { + form.findField('hw_denoise').setDisabled(!form.findField('hwaccel').getValue()); + form.findField('hw_sharpness').setDisabled(!form.findField('hwaccel').getValue()); + form.findField('hwaccel_details').setDisabled(!form.findField('hwaccel').getValue()); + } +} + +function checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field, ui_value, uilp_value) { + // enable max B frames based on ui (vainfo) + let uibframe = 0; + if (low_power_field.getValue()) { + // low power is enabled + uibframe = (uilp_value & 0xe) >> 1 + } + else { + // low power is disabled + uibframe = (ui_value & 0xe) >> 1 + } + // messagebox if max B grames > VAINFO.max_b_frames + if (uibframe) { + if (desired_b_depth_field.getValue() > uibframe) + alert('VAINFO maximum B fames is: ' + uibframe) + desired_b_depth_field.setDisabled(false); + b_reference_field.setDisabled(false); + } + else { + desired_b_depth_field.setDisabled(true); + b_reference_field.setDisabled(true); + } + // enable Quality based on ui (vainfo) + let uiquality = 0; + if (low_power_field.getValue()) { + // low power is enabled + uiquality = (uilp_value & 0xf0) >> 4 + } + else { + // low power is disabled + uiquality = (ui_value & 0xf0) >> 4 + } + // messagebox if Qality > VAINFO.quality + if (uiquality > 1) { + if (quality_field.getValue() > uiquality) + alert('VAINFO maximum Quality is: ' + uiquality) + } + else { + quality_field.setValue(-1); + quality_field.setDisabled(true); + } +} + +function updateLowPower(form) { + if (form.findField('low_power') && form.findField('desired_b_depth') && + form.findField('b_reference') && form.findField('quality') && + form.findField('ui') && form.findField('uilp')) + { + checkBFrameQuality( form.findField('low_power'), form.findField('desired_b_depth'), + form.findField('b_reference'), form.findField('quality'), + form.findField('ui').getValue(), form.findField('uilp').getValue()); + } +} + +function removeConstrains(form) { + const arr_fields = ['bit_rate', 'max_bit_rate', 'buff_factor', 'bit_rate_scale_factor', 'qp', 'low_power', 'desired_b_depth', 'b_reference', 'quality']; + for (const str_field of arr_fields) + if (form.findField(str_field)) + form.findField(str_field).setDisabled(false); +} + +function update_rc_settings(form, bit_rate_value, max_bit_rate_value, buff_factor_value, bit_rate_scale_factor_value, qp_value) { + if (form.findField('bit_rate') && form.findField('max_bit_rate') && + form.findField('buff_factor') && form.findField('bit_rate_scale_factor') && + form.findField('qp')) + { + form.findField('bit_rate').setDisabled(bit_rate_value); + form.findField('max_bit_rate').setDisabled(max_bit_rate_value); + form.findField('buff_factor').setDisabled(buff_factor_value); + form.findField('bit_rate_scale_factor').setDisabled(bit_rate_scale_factor_value); + form.findField('qp').setDisabled(qp_value); + } +} + +function filter_based_on_rc(form) { + if (form.findField('rc_mode')) { + switch (form.findField('rc_mode').getValue()) { + case -1: + case 0: + // for auto --> let the driver decide as requested by documentation + update_rc_settings(form, false, false, false, false, false); + break; + case 1: + case 4: + // for constant quality: CQP and ICQ we use qp + update_rc_settings(form, true, true, true, true, false); + break; + case 2: + // for constant bitrate: CBR we use bitrate + update_rc_settings(form, false, true, false, false, true); + break; + case 3: + // for variable bitrate: VBR we use bitrate + update_rc_settings(form, false, false, false, false, true); + break; + case 5: + // for variable bitrate: QVBR we use bitrate + qp + update_rc_settings(form, false, false, false, false, false); + break; + case 6: + // for variable bitrate: AVBR we use bitrate + update_rc_settings(form, false, false, true, false, true); + break; + } + } +} + +function update_intel_low_power(form) { + if (form.findField('ui') && form.findField('uilp')){ + let ui_value = form.findField('ui').getValue(); + let uilp_value = form.findField('uilp').getValue(); + if (form.findField('low_power')){ + // enable low_power mode based on ui (vainfo) + if ((ui_value & 0x1) && (uilp_value & 0x1)) + form.findField('low_power').setDisabled(false); + else { + form.findField('low_power').setDisabled(true); + if (uilp_value & 0x1) + // only low power is available + form.findField('low_power').setValue(true); + if (ui_value & 0x1) + // only normal is available + form.findField('low_power').setValue(false); + } + updateLowPower(form); + } + } +} + +function updateFilters(form) { + if (form.findField('platform')){ + switch (form.findField('platform').getValue()) { + case 0: + // Unconstrained --> will allow any combination of parameters (valid or invalid) + // this mode is usefull fur future platform and for debugging. + // no filter applied + removeConstrains(form); + break; + case 1: + // Intel + update_intel_low_power(form); + // filter based in rc_mode + filter_based_on_rc(form); + break; + case 2: + // AMD --> will allow any combination of parameters + // I am unable to confirm this platform because I don't have the HW + // Is only going to override bf to 0 (as highlited by the previous implementation) + // NOTE: filters to be added later + removeConstrains(form); + break; + default: + } + } +} + + +function update_vaapi_ui(form) { + // first time we have to call this manually + updateFilters(form); + updateHWFilters(form); + + // on platform change + if (form.findField('platform')) + form.findField('platform').on('select', function(combo, record, index) { + updateFilters(form); + }); + + // on rc_mode change + if (form.findField('rc_mode')) + form.findField('rc_mode').on('select', function(combo, record, index) { + updateFilters(form); + }); + + // on low_power change + if (form.findField('low_power')) + form.findField('low_power').on('check', function(checkbox, value) { + updateLowPower(form); + }); + + // on hwaccel change + if (form.findField('hwaccel')) + form.findField('hwaccel').on('check', function(checkbox, value) { + updateHWFilters(form); + }); + + // on desired_b_depth change + if (form.findField('desired_b_depth')) + form.findField('desired_b_depth').on('spin', function(spinner, direction, eOpts) { + updateFilters(form); + }); + + // on quality change + if (form.findField('quality')) + form.findField('quality').on('spin', function(spinner, direction, eOpts) { + updateFilters(form); + }); +} var codec_profile_forms = { 'default': function(form) { @@ -31,7 +257,10 @@ var codec_profile_forms = { name_field.maxLength = 31; // TVH_NAME_LEN -1 }, - 'codec_profile_mpeg2video': genericCBRvsVBR, + 'codec_profile_mpeg2video': function(form) { + genericCBRvsVBR(form); + enable_hwaccels_details(form); + }, 'codec_profile_mp2': function(form) { function makeData(list) { @@ -127,9 +356,23 @@ var codec_profile_forms = { }); }, - 'codec_profile_libx264': genericCBRvsVBR, + //'codec_profile_vorbis': function(form) { + // + //}, - 'codec_profile_libx265': genericCBRvsVBR, + //'codec_profile_flac': function(form) { + // + //}, + + 'codec_profile_libx264': function(form) { + genericCBRvsVBR(form); + enable_hwaccels_details(form); + }, + + 'codec_profile_libx265': function(form) { + genericCBRvsVBR(form); + enable_hwaccels_details(form); + }, 'codec_profile_libvpx': function(form) { function updateSpeed(quality_f, speed_f) { @@ -142,6 +385,7 @@ var codec_profile_forms = { } genericCBRvsVBR(form); + enable_hwaccels_details(form); var quality_field = form.findField('deadline'); var speed_field = form.findField('cpu-used'); updateSpeed(quality_field, speed_field); @@ -158,6 +402,10 @@ var codec_profile_forms = { 'codec_profile_libvorbis': genericCBRvsVBR, + //'codec_profile_libopus': function(form) { + // + //}, + 'codec_profile_libfdk_aac': function(form) { // TODO: max bitrate // max vbr = 5 for FF_PROFILE_UNKNOWN(-99) and FF_PROFILE_AAC_LOW(1) @@ -230,899 +478,27 @@ var codec_profile_forms = { }, 'codec_profile_vaapi_h264': function(form) { - function updateHWFilters(form) { - var hwaccel_field = form.findField('hwaccel'); - form.findField('hw_denoise').setDisabled(!hwaccel_field.getValue()); - form.findField('hw_sharpness').setDisabled(!hwaccel_field.getValue()); - } - - function checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field) { - // enable max B frames based on ui (vainfo) - var uibframe = 0; - if (low_power_field.getValue()) { - // low power is enabled - uibframe = (uilp_value & 0xe) >> 1 - } - else { - // low power is disabled - uibframe = (ui_value & 0xe) >> 1 - } - // messagebox if max B grames > VAINFO.max_b_frames - if (uibframe) { - if (desired_b_depth_field.getValue() > uibframe) - alert('VAINFO maximum B fames is: ' + uibframe) - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - } - else { - desired_b_depth_field.setDisabled(true); - b_reference_field.setDisabled(true); - } - // enable Quality based on ui (vainfo) - var uiquality = 0; - if (low_power_field.getValue()) { - // low power is enabled - uiquality = (uilp_value & 0xf0) >> 4 - } - else { - // low power is disabled - uiquality = (ui_value & 0xf0) >> 4 - } - // messagebox if Qality > VAINFO.quality - if (uiquality > 1) { - if (quality_field.getValue() > uiquality) - alert('VAINFO maximum Quality is: ' + uiquality) - } - else { - quality_field.setValue(-1); - quality_field.setDisabled(true); - } - } - - function updateLowPower(form) { - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - } - - function removeConstrains(form) { - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - low_power_field.setDisabled(false); - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - quality_field.setDisabled(false); - } - - function updateFilters(form, ui_value, uilp_value) { - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - var platform = platform_field.getValue(); - switch (platform) { - case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - // no filter applied - removeConstrains(form); - break; - case 1: - // Intel - // enable low_power mode based on ui (vainfo) - if ((ui_value & 0x1) && (uilp_value & 0x1)) - low_power_field.setDisabled(false); - else { - low_power_field.setDisabled(true); - if (uilp_value & 0x1) - // only low power is available - low_power_field.setValue(true); - if (ui_value & 0x1) - // only normal is available - low_power_field.setValue(false); - } - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - // filter based in rc_mode - var rc_mode = rc_mode_field.getValue(); - switch (rc_mode) { - case -1: - case 0: - // for auto --> let the driver decide as requested by documentation - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - bit_rate_field.setDisabled(true); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(true); - qp_field.setDisabled(false); - break; - case 2: - // for constant bitrate: CBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 3: - // for variable bitrate: VBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 6: - // for variable bitrate: AVBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - } - break; - case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - // NOTE: filters to be added later - removeConstrains(form); - break; - default: - } - } - - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var low_power_field = form.findField('low_power'); - var hwaccel_field = form.findField('hwaccel'); - var ui_field = form.findField('ui'); - var uilp_field = form.findField('uilp'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var quality_field = form.findField('quality'); - var ui_value = ui_field.getValue(); - var uilp_value = uilp_field.getValue(); - - // first time we have to call this manually - updateFilters(form, ui_value, uilp_value); - updateHWFilters(form); - - // on platform change - platform_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on rc_mode change - rc_mode_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on low_power change - low_power_field.on('check', function(checkbox, value) { - updateLowPower(form); - }); - // on hwaccel change - hwaccel_field.on('check', function(checkbox, value) { - updateHWFilters(form); - }); - // on desired_b_depth change - desired_b_depth_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); - // on quality change - quality_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); + update_vaapi_ui(form); }, 'codec_profile_vaapi_hevc': function(form) { - function updateHWFilters(form) { - var hwaccel_field = form.findField('hwaccel'); - form.findField('hw_denoise').setDisabled(!hwaccel_field.getValue()); - form.findField('hw_sharpness').setDisabled(!hwaccel_field.getValue()); - } - - function checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field) { - // enable max B frames based on ui (vainfo) - var uibframe = 0; - if (low_power_field.getValue()) { - // low power is enabled - uibframe = (uilp_value & 0xe) >> 1 - } - else { - // low power is disabled - uibframe = (ui_value & 0xe) >> 1 - } - // messagebox if max B grames > VAINFO.max_b_frames - if (uibframe) { - if (desired_b_depth_field.getValue() > uibframe) - alert('VAINFO maximum B fames is: ' + uibframe) - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - } - else { - desired_b_depth_field.setDisabled(true); - b_reference_field.setDisabled(true); - } - // enable Quality based on ui (vainfo) - var uiquality = 0; - if (low_power_field.getValue()) { - // low power is enabled - uiquality = (uilp_value & 0xf0) >> 4 - } - else { - // low power is disabled - uiquality = (ui_value & 0xf0) >> 4 - } - // messagebox if Qality > VAINFO.quality - if (uiquality > 1) { - if (quality_field.getValue() > uiquality) - alert('VAINFO maximum Quality is: ' + uiquality) - } - else { - quality_field.setValue(-1); - quality_field.setDisabled(true); - } - } - - function updateLowPower(form) { - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - } - - function removeConstrains(form) { - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - low_power_field.setDisabled(false); - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - quality_field.setDisabled(false); - } - - function updateFilters(form, ui_value, uilp_value) { - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - var platform = platform_field.getValue(); - switch (platform) { - case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - // no filter applied - removeConstrains(form); - break; - case 1: - // Intel - // enable low_power mode based on ui (vainfo) - if ((ui_value & 0x1) && (uilp_value & 0x1)) - low_power_field.setDisabled(false); - else { - low_power_field.setDisabled(true); - if (uilp_value & 0x1) - // only low power is available - low_power_field.setValue(true); - if (ui_value & 0x1) - // only normal is available - low_power_field.setValue(false); - } - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - // filter based in rc_mode - var rc_mode = rc_mode_field.getValue(); - switch (rc_mode) { - case -1: - case 0: - // for auto --> let the driver decide as requested by documentation - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - bit_rate_field.setDisabled(true); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(true); - qp_field.setDisabled(false); - break; - case 2: - // for constant bitrate: CBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 3: - // for variable bitrate: VBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 6: - // for variable bitrate: AVBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - } - break; - case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - // NOTE: filters to be added later - removeConstrains(form); - break; - default: - } - } - - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var low_power_field = form.findField('low_power'); - var hwaccel_field = form.findField('hwaccel'); - var ui_field = form.findField('ui'); - var uilp_field = form.findField('uilp'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var quality_field = form.findField('quality'); - var ui_value = ui_field.getValue(); - var uilp_value = uilp_field.getValue(); - - // first time we have to call this manually - updateFilters(form, ui_value, uilp_value); - updateHWFilters(form); - - // on platform change - platform_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on rc_mode change - rc_mode_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on low_power change - low_power_field.on('check', function(checkbox, value) { - updateLowPower(form); - }); - // on hwaccel change - hwaccel_field.on('check', function(checkbox, value) { - updateHWFilters(form); - }); - // on desired_b_depth change - desired_b_depth_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); - // on quality change - quality_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); + update_vaapi_ui(form); }, 'codec_profile_vaapi_vp8': function(form) { - function updateHWFilters(form) { - var hwaccel_field = form.findField('hwaccel'); - form.findField('hw_denoise').setDisabled(!hwaccel_field.getValue()); - form.findField('hw_sharpness').setDisabled(!hwaccel_field.getValue()); - } - - function checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field) { - // enable max B frames based on ui (vainfo) - var uibframe = 0; - if (low_power_field.getValue()) { - // low power is enabled - uibframe = (uilp_value & 0xe) >> 1 - } - else { - // low power is disabled - uibframe = (ui_value & 0xe) >> 1 - } - // messagebox if max B grames > VAINFO.max_b_frames - if (uibframe) { - if (desired_b_depth_field.getValue() > uibframe) - alert('VAINFO maximum B fames is: ' + uibframe) - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - } - else { - desired_b_depth_field.setDisabled(true); - b_reference_field.setDisabled(true); - } - // enable Quality based on ui (vainfo) - var uiquality = 0; - if (low_power_field.getValue()) { - // low power is enabled - uiquality = (uilp_value & 0xf0) >> 4 - } - else { - // low power is disabled - uiquality = (ui_value & 0xf0) >> 4 - } - // messagebox if Qality > VAINFO.quality - if (uiquality > 1) { - if (quality_field.getValue() > uiquality) - alert('VAINFO maximum Quality is: ' + uiquality) - } - else { - quality_field.setValue(-1); - quality_field.setDisabled(true); - } - } - - function updateLowPower(form) { - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - } - - function removeConstrains(form) { - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - low_power_field.setDisabled(false); - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - quality_field.setDisabled(false); - } - - function updateFilters(form, ui_value, uilp_value) { - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - var platform = platform_field.getValue(); - switch (platform) { - case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - // no filter applied - removeConstrains(form); - break; - case 1: - // Intel - // enable low_power mode based on ui (vainfo) - if ((ui_value & 0x1) && (uilp_value & 0x1)) - low_power_field.setDisabled(false); - else { - low_power_field.setDisabled(true); - if (uilp_value & 0x1) - // only low power is available - low_power_field.setValue(true); - if (ui_value & 0x1) - // only normal is available - low_power_field.setValue(false); - } - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - // filter based in rc_mode - var rc_mode = rc_mode_field.getValue(); - switch (rc_mode) { - case -1: - case 0: - // for auto --> let the driver decide as requested by documentation - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - bit_rate_field.setDisabled(true); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(true); - qp_field.setDisabled(false); - break; - case 2: - // for constant bitrate: CBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 3: - // for variable bitrate: VBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 6: - // for variable bitrate: AVBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - } - break; - case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - // NOTE: filters to be added later - removeConstrains(form); - break; - default: - } - } - - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var low_power_field = form.findField('low_power'); - var hwaccel_field = form.findField('hwaccel'); - var ui_field = form.findField('ui'); - var uilp_field = form.findField('uilp'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var quality_field = form.findField('quality'); - var ui_value = ui_field.getValue(); - var uilp_value = uilp_field.getValue(); - - // first time we have to call this manually - updateFilters(form, ui_value, uilp_value); - updateHWFilters(form); - - // on platform change - platform_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on rc_mode change - rc_mode_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on low_power change - low_power_field.on('check', function(checkbox, value) { - updateLowPower(form); - }); - // on hwaccel change - hwaccel_field.on('check', function(checkbox, value) { - updateHWFilters(form); - }); - // on desired_b_depth change - desired_b_depth_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); - // on quality change - quality_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); + update_vaapi_ui(form); }, 'codec_profile_vaapi_vp9': function(form) { - function updateHWFilters(form) { - var hwaccel_field = form.findField('hwaccel'); - form.findField('hw_denoise').setDisabled(!hwaccel_field.getValue()); - form.findField('hw_sharpness').setDisabled(!hwaccel_field.getValue()); - } - - function checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field) { - // enable max B frames based on ui (vainfo) - var uibframe = 0; - if (low_power_field.getValue()) { - // low power is enabled - uibframe = (uilp_value & 0xe) >> 1 - } - else { - // low power is disabled - uibframe = (ui_value & 0xe) >> 1 - } - // messagebox if max B grames > VAINFO.max_b_frames - if (uibframe) { - if (desired_b_depth_field.getValue() > uibframe) - alert('VAINFO maximum B fames is: ' + uibframe) - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - } - else { - desired_b_depth_field.setDisabled(true); - b_reference_field.setDisabled(true); - } - // enable Quality based on ui (vainfo) - var uiquality = 0; - if (low_power_field.getValue()) { - // low power is enabled - uiquality = (uilp_value & 0xf0) >> 4 - } - else { - // low power is disabled - uiquality = (ui_value & 0xf0) >> 4 - } - // messagebox if Qality > VAINFO.quality - if (uiquality > 1) { - if (quality_field.getValue() > uiquality) - alert('VAINFO maximum Quality is: ' + uiquality) - } - else { - quality_field.setValue(-1); - quality_field.setDisabled(true); - } - } - - function updateLowPower(form) { - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - } - - function removeConstrains(form) { - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); - - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - low_power_field.setDisabled(false); - desired_b_depth_field.setDisabled(false); - b_reference_field.setDisabled(false); - quality_field.setDisabled(false); - } - - function updateFilters(form, ui_value, uilp_value) { - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var bit_rate_field = form.findField('bit_rate'); - var max_bit_rate_field = form.findField('max_bit_rate'); - var buff_factor_field = form.findField('buff_factor'); - var bit_rate_scale_factor_field = form.findField('bit_rate_scale_factor'); - var qp_field = form.findField('qp'); - var low_power_field = form.findField('low_power'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var b_reference_field = form.findField('b_reference'); - var quality_field = form.findField('quality'); + update_vaapi_ui(form); + }, - var platform = platform_field.getValue(); - switch (platform) { - case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - // no filter applied - removeConstrains(form); - break; - case 1: - // Intel - // enable low_power mode based on ui (vainfo) - if ((ui_value & 0x1) && (uilp_value & 0x1)) - low_power_field.setDisabled(false); - else { - low_power_field.setDisabled(true); - if (uilp_value & 0x1) - // only low power is available - low_power_field.setValue(true); - if (ui_value & 0x1) - // only normal is available - low_power_field.setValue(false); - } - checkBFrameQuality(low_power_field, desired_b_depth_field, b_reference_field, quality_field); - // filter based in rc_mode - var rc_mode = rc_mode_field.getValue(); - switch (rc_mode) { - case -1: - case 0: - // for auto --> let the driver decide as requested by documentation - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - bit_rate_field.setDisabled(true); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(true); - qp_field.setDisabled(false); - break; - case 2: - // for constant bitrate: CBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(true); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 3: - // for variable bitrate: VBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(false); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(false); - break; - case 6: - // for variable bitrate: AVBR we use bitrate - bit_rate_field.setDisabled(false); - max_bit_rate_field.setDisabled(false); - buff_factor_field.setDisabled(true); - bit_rate_scale_factor_field.setDisabled(false); - qp_field.setDisabled(true); - break; - } - break; - case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - // NOTE: filters to be added later - removeConstrains(form); - break; - default: - } - } + 'codec_profile_nvenc_h264': function(form) { + enable_hwaccels_details(form); + }, - var platform_field = form.findField('platform'); - var rc_mode_field = form.findField('rc_mode'); - var low_power_field = form.findField('low_power'); - var hwaccel_field = form.findField('hwaccel'); - var ui_field = form.findField('ui'); - var uilp_field = form.findField('uilp'); - var desired_b_depth_field = form.findField('desired_b_depth'); - var quality_field = form.findField('quality'); - var ui_value = ui_field.getValue(); - var uilp_value = uilp_field.getValue(); - - // first time we have to call this manually - updateFilters(form, ui_value, uilp_value); - updateHWFilters(form); - - // on platform change - platform_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on rc_mode change - rc_mode_field.on('select', function(combo, record, index) { - updateFilters(form, ui_value, uilp_value); - }); - // on low_power change - low_power_field.on('check', function(checkbox, value) { - updateLowPower(form); - }); - // on hwaccel change - hwaccel_field.on('check', function(checkbox, value) { - updateHWFilters(form); - }); - // on desired_b_depth change - desired_b_depth_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); - // on quality change - quality_field.on('spin', function(spinner, direction, eOpts) { - updateFilters(form, ui_value, uilp_value); - }); + 'codec_profile_nvenc_hevc': function(form) { + enable_hwaccels_details(form); } };