summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott <[email protected]>2018-06-29 19:48:26 +0100
committerGitHub <[email protected]>2018-06-29 19:48:26 +0100
commitdbf898635dc12608b78c33916137465ce08937bf (patch)
tree2449891c1f1275e43673b9aa276b8e8905374b55
parentac390b630498163ff37bea491202c0872bb679ec (diff)
Add NVEnc encoder. (Round 3) (#1437)
Adding the Nvidia NVEnc H.264 and H.265 encoders. Based on Initial work by sgothel --enable-nvenc is the new compile time configure option to enable for builds.
-rw-r--r--contrib/ffmpeg/module.defs12
-rw-r--r--contrib/nvenc/module.defs12
-rw-r--r--contrib/nvenc/module.rules2
-rw-r--r--libhb/common.c81
-rw-r--r--libhb/common.h8
-rw-r--r--libhb/encavcodec.c109
-rw-r--r--libhb/hbffmpeg.h5
-rw-r--r--libhb/module.defs4
-rw-r--r--libhb/muxavformat.c2
-rw-r--r--libhb/nvenc_common.c57
-rw-r--r--libhb/nvenc_common.h11
-rw-r--r--libhb/work.c15
-rw-r--r--make/configure.py5
-rw-r--r--make/include/main.defs4
-rw-r--r--test/module.defs4
-rw-r--r--win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs6
-rw-r--r--win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs10
-rw-r--r--win/CS/HandBrake.Interop/Utilities/SystemInfo.cs50
-rw-r--r--win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs10
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs27
20 files changed, 383 insertions, 51 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
index 63924ad96..e24a897b9 100644
--- a/contrib/ffmpeg/module.defs
+++ b/contrib/ffmpeg/module.defs
@@ -5,6 +5,9 @@ endif
ifeq (1,$(FEATURE.vce))
__deps__ += AMF
endif
+ifeq (1,$(FEATURE.nvenc))
+__deps__ += NVENC
+endif
$(eval $(call import.MODULE.defs,FFMPEG,ffmpeg,$(__deps__)))
$(eval $(call import.CONTRIB.defs,FFMPEG))
@@ -107,7 +110,14 @@ ifeq (1,$(FEATURE.qsv))
endif
ifeq (1,$(FEATURE.vce))
- FFMPEG.CONFIGURE.extra += --enable-amf --enable-encoder=h264_amf --enable-encoder=hevc_amf
+ FFMPEG.CONFIGURE.extra += --enable-amf --enable-encoder=h264_amf --enable-encoder=hevc_amf
+endif
+
+ifeq (1,$(FEATURE.nvenc))
+FFMPEG.CONFIGURE.extra += \
+ --enable-nvenc \
+ --enable-encoder=h264_nvenc \
+ --enable-encoder=hevc_nvenc
endif
## enable compile verbosity
diff --git a/contrib/nvenc/module.defs b/contrib/nvenc/module.defs
new file mode 100644
index 000000000..e040b9ade
--- /dev/null
+++ b/contrib/nvenc/module.defs
@@ -0,0 +1,12 @@
+$(eval $(call import.MODULE.defs,NVENC,nvenc))
+$(eval $(call import.CONTRIB.defs,NVENC))
+
+NVENC.FETCH.url = https://download.handbrake.fr/contrib/nv-codec-headers-8.1.24.2.tar.gz
+NVENC.FETCH.url += https://github.com/FFmpeg/nv-codec-headers/releases/download/n8.1.24.2/nv-codec-headers-8.1.24.2.tar.gz
+NVENC.FETCH.sha256 = 2b339b2493f5b63b285dd660be05102af7d4ff2de9fcf3af94e48b5f91a3ca57
+NVENC.EXTRACT.tarbase = nv-codec-headers-n8.1.24.2
+
+NVENC.CONFIGURE = $(TOUCH.exe) $@
+NVENC.BUILD.extra = PREFIX="$(NVENC.CONFIGURE.prefix)"
+NVENC.INSTALL.extra = PREFIX="$(NVENC.CONFIGURE.prefix)"
+NVENC.UNINSTALL.extra = PREFIX="$(NVENC.CONFIGURE.prefix)"
diff --git a/contrib/nvenc/module.rules b/contrib/nvenc/module.rules
new file mode 100644
index 000000000..976986a57
--- /dev/null
+++ b/contrib/nvenc/module.rules
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,NVENC))
+$(eval $(call import.CONTRIB.rules,NVENC))
diff --git a/libhb/common.c b/libhb/common.c
index a4c84198f..e8a1dee9f 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -31,6 +31,10 @@
#include <windows.h>
#endif
+#ifdef USE_QSV
+#include "nvenc_common.h"
+#endif
+
static int mixdown_get_opus_coupled_stream_count(int mixdown);
/**********************************************************************
@@ -228,27 +232,29 @@ hb_encoder_t *hb_video_encoders_last_item = NULL;
hb_encoder_internal_t hb_video_encoders[] =
{
// legacy encoders, back to HB 0.9.4 whenever possible (disabled)
- { { "FFmpeg", "ffmpeg", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
- { { "MPEG-4 (FFmpeg)", "ffmpeg4", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
- { { "MPEG-2 (FFmpeg)", "ffmpeg2", NULL, HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG2, },
+ { { "FFmpeg", "ffmpeg", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
+ { { "MPEG-4 (FFmpeg)", "ffmpeg4", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
+ { { "MPEG-2 (FFmpeg)", "ffmpeg2", NULL, HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG2, },
{ { "VP3 (Theora)", "libtheora", NULL, HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_THEORA, },
// actual encoders
{ { "H.264 (x264)", "x264", "H.264 (libx264)", HB_VCODEC_X264_8BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "H.264 10-bit (x264)", "x264_10bit", "H.264 10-bit (libx264)", HB_VCODEC_X264_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "H.264 (Intel QSV)", "qsv_h264", "H.264 (Intel Media SDK)", HB_VCODEC_QSV_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "H.264 (AMD VCE)", "vce_h264", "H.264 (libavcodec)", HB_VCODEC_FFMPEG_VCE_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "H.265 (x265)", "x265", "H.265 (libx265)", HB_VCODEC_X265_8BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 10-bit (x265)", "x265_10bit", "H.265 10-bit (libx265)", HB_VCODEC_X265_10BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 12-bit (x265)", "x265_12bit", "H.265 12-bit (libx265)", HB_VCODEC_X265_12BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 16-bit (x265)", "x265_16bit", "H.265 16-bit (libx265)", HB_VCODEC_X265_16BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 (Intel QSV)", "qsv_h265", "H.265 (Intel Media SDK)", HB_VCODEC_QSV_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 10-bit (Intel QSV)", "qsv_h265_10bit", "H.265 10-bit (Intel Media SDK)", HB_VCODEC_QSV_H265_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
- { { "H.265 (AMD VCE)", "vce_h265", "H.265 (libavcodec)", HB_VCODEC_FFMPEG_VCE_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "MPEG-4", "mpeg4", "MPEG-4 (libavcodec)", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG4, },
- { { "MPEG-2", "mpeg2", "MPEG-2 (libavcodec)", HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG2, },
- { { "VP8", "VP8", "VP8 (libvpx)", HB_VCODEC_FFMPEG_VP8, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_VP8, },
- { { "VP9", "VP9", "VP9 (libvpx)", HB_VCODEC_FFMPEG_VP9, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_VP9, },
- { { "Theora", "theora", "Theora (libtheora)", HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_THEORA, },
+ { { "H.264 10-bit (x264)", "x264_10bit", "H.264 10-bit (libx264)", HB_VCODEC_X264_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.264 (Intel QSV)", "qsv_h264", "H.264 (Intel Media SDK)", HB_VCODEC_QSV_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.264 (AMD VCE)", "vce_h264", "H.264 (libavcodec)", HB_VCODEC_FFMPEG_VCE_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.264 (NVEnc)", "nvenc_h264", "H.264 (libavcodec)", HB_VCODEC_FFMPEG_NVENC_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.265 (x265)", "x265", "H.265 (libx265)", HB_VCODEC_X265_8BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 10-bit (x265)", "x265_10bit", "H.265 10-bit (libx265)", HB_VCODEC_X265_10BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 12-bit (x265)", "x265_12bit", "H.265 12-bit (libx265)", HB_VCODEC_X265_12BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 16-bit (x265)", "x265_16bit", "H.265 16-bit (libx265)", HB_VCODEC_X265_16BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 (Intel QSV)", "qsv_h265", "H.265 (Intel Media SDK)", HB_VCODEC_QSV_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 10-bit (Intel QSV)","qsv_h265_10bit", "H.265 10-bit (Intel Media SDK)", HB_VCODEC_QSV_H265_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 (AMD VCE)", "vce_h265", "H.265 (libavcodec)", HB_VCODEC_FFMPEG_VCE_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "H.265 (NVEnc)", "nvenc_h265", "H.265 (libavcodec)", HB_VCODEC_FFMPEG_NVENC_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H265, },
+ { { "MPEG-4", "mpeg4", "MPEG-4 (libavcodec)", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG4, },
+ { { "MPEG-2", "mpeg2", "MPEG-2 (libavcodec)", HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG2, },
+ { { "VP8", "VP8", "VP8 (libvpx)", HB_VCODEC_FFMPEG_VP8, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_VP8, },
+ { { "VP9", "VP9", "VP9 (libvpx)", HB_VCODEC_FFMPEG_VP9, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_VP9, },
+ { { "Theora", "theora", "Theora (libtheora)", HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_THEORA, },
};
int hb_video_encoders_count = sizeof(hb_video_encoders) / sizeof(hb_video_encoders[0]);
static int hb_video_encoder_is_enabled(int encoder)
@@ -275,6 +281,13 @@ static int hb_video_encoder_is_enabled(int encoder)
return 1;
#endif
+#ifdef USE_NVENC
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ return hb_nvenc_h264_available();
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ return hb_nvenc_h265_available();
+#endif
+
#ifdef USE_X265
case HB_VCODEC_X265_8BIT:
case HB_VCODEC_X265_10BIT:
@@ -1305,6 +1318,8 @@ void hb_video_quality_get_limits(uint32_t codec, float *low, float *high,
*/
case HB_VCODEC_X264_8BIT:
case HB_VCODEC_X265_8BIT:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
*direction = 1;
*granularity = 0.1;
*low = 0.;
@@ -1377,6 +1392,8 @@ const char* hb_video_quality_get_name(uint32_t codec)
case HB_VCODEC_FFMPEG_VP8:
case HB_VCODEC_FFMPEG_VP9:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
return "CQ";
default:
@@ -1484,7 +1501,10 @@ const char* const* hb_video_encoder_get_profiles(int encoder)
return hb_h264_profile_names_8bit;
case HB_VCODEC_FFMPEG_VCE_H265:
return hb_h265_profile_names_8bit;
-
+
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ return hb_av_profile_get_names(encoder);
default:
return NULL;
}
@@ -1499,23 +1519,22 @@ const char* const* hb_video_encoder_get_levels(int encoder)
}
#endif
-#ifdef USE_VCE
- if (encoder & HB_VCODEC_FFMPEG_VCE_H264)
- {
- return hb_h264_level_names;
- }
-
- if (encoder & HB_VCODEC_FFMPEG_VCE_H265)
- {
- return hb_h265_level_names;
- }
-#endif
-
switch (encoder)
{
case HB_VCODEC_X264_8BIT:
case HB_VCODEC_X264_10BIT:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_VCE_H264:
+ return hb_h264_level_names;
+
+ case HB_VCODEC_X265_8BIT:
+ case HB_VCODEC_X265_10BIT:
+ case HB_VCODEC_X265_12BIT:
+ case HB_VCODEC_X265_16BIT:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ case HB_VCODEC_FFMPEG_VCE_H265:
return hb_h264_level_names;
+
default:
return NULL;
diff --git a/libhb/common.h b/libhb/common.h
index a91d608c9..1d28ada4c 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -510,7 +510,9 @@ struct hb_job_s
#define HB_VCODEC_FFMPEG_VP9 0x0000080
#define HB_VCODEC_FFMPEG_VCE_H264 0x00040000
#define HB_VCODEC_FFMPEG_VCE_H265 0x00080000
-#define HB_VCODEC_FFMPEG_MASK (0x00000F0|HB_VCODEC_FFMPEG_VCE_H264|HB_VCODEC_FFMPEG_VCE_H265)
+#define HB_VCODEC_FFMPEG_NVENC_H264 0x00160000
+#define HB_VCODEC_FFMPEG_NVENC_H265 0x00320000
+#define HB_VCODEC_FFMPEG_MASK (0x00000F0|HB_VCODEC_FFMPEG_VCE_H264|HB_VCODEC_FFMPEG_VCE_H265|HB_VCODEC_FFMPEG_NVENC_H264|HB_VCODEC_FFMPEG_NVENC_H265)
#define HB_VCODEC_QSV_H264 0x0000100
#define HB_VCODEC_QSV_H265_8BIT 0x0000200
#define HB_VCODEC_QSV_H265_10BIT 0x0000400
@@ -521,14 +523,14 @@ struct hb_job_s
#define HB_VCODEC_X264 HB_VCODEC_X264_8BIT
#define HB_VCODEC_X264_10BIT 0x0020000
#define HB_VCODEC_X264_MASK 0x0030000
-#define HB_VCODEC_H264_MASK (HB_VCODEC_X264_MASK|HB_VCODEC_QSV_H264|HB_VCODEC_FFMPEG_VCE_H264)
+#define HB_VCODEC_H264_MASK (HB_VCODEC_X264_MASK|HB_VCODEC_QSV_H264|HB_VCODEC_FFMPEG_VCE_H264|HB_VCODEC_FFMPEG_NVENC_H264)
#define HB_VCODEC_X265_8BIT 0x0001000
#define HB_VCODEC_X265 HB_VCODEC_X265_8BIT
#define HB_VCODEC_X265_10BIT 0x0002000
#define HB_VCODEC_X265_12BIT 0x0004000
#define HB_VCODEC_X265_16BIT 0x0008000
#define HB_VCODEC_X265_MASK 0x000F000
-#define HB_VCODEC_H265_MASK (HB_VCODEC_X265_MASK|HB_VCODEC_QSV_H265_MASK|HB_VCODEC_FFMPEG_VCE_H265)
+#define HB_VCODEC_H265_MASK (HB_VCODEC_X265_MASK|HB_VCODEC_QSV_H265_MASK|HB_VCODEC_FFMPEG_VCE_H265|HB_VCODEC_FFMPEG_NVENC_H265)
/* define an invalid CQ value compatible with all CQ-capable codecs */
#define HB_INVALID_VIDEO_QUALITY (-1000.)
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
index ee914faba..17a6fdb25 100644
--- a/libhb/encavcodec.c
+++ b/libhb/encavcodec.c
@@ -68,6 +68,22 @@ static const char * const vpx_preset_names[] =
"veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", NULL
};
+static const char * const h26x_nvenc_preset_names[] =
+{
+ "losslesshp", "lossless", "llhp", "llhq", "ll", "bd", "hq", "hp", "fast", "medium", "slow", "default", NULL
+};
+
+static const char * const h264_nvenc_profile_names[] =
+{
+ "auto", "baseline", "main", "high", NULL // "high444p" not supported.
+};
+
+static const char * const h265_nvenc_profile_names[] =
+{
+ "auto", "main", "main10", "rext", NULL
+};
+
+
int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
{
int ret = 0;
@@ -75,6 +91,7 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
AVCodec * codec;
AVCodecContext * context;
AVRational fps;
+ int64_t bit_rate_ceiling = -1;
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
@@ -110,13 +127,29 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
} break;
case AV_CODEC_ID_H264:
{
- hb_log("encavcodecInit: H.264 (AMD VCE)");
- codec = avcodec_find_encoder_by_name("h264_amf");
+ switch (job->vcodec) {
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ hb_log("encavcodecInit: H.264 (Nvidia NVENC)");
+ codec = avcodec_find_encoder_by_name("h264_nvenc");
+ break;
+ case HB_VCODEC_FFMPEG_VCE_H264:
+ hb_log("encavcodecInit: H.264 (AMD VCE)");
+ codec = avcodec_find_encoder_by_name("h264_amf");
+ break;
+ }
}break;
case AV_CODEC_ID_HEVC:
{
- hb_log("encavcodecInit: H.265 (AMD VCE)");
- codec = avcodec_find_encoder_by_name("hevc_amf");
+ switch (job->vcodec) {
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ hb_log("encavcodecInit: H.265 (Nvidia NVENC)");
+ codec = avcodec_find_encoder_by_name("hevc_nvenc");
+ break;
+ case HB_VCODEC_FFMPEG_VCE_H264:
+ hb_log("encavcodecInit: H.265 (AMD VCE)");
+ codec = avcodec_find_encoder_by_name("hevc_amf");
+ break;
+ }
}break;
default:
{
@@ -213,6 +246,8 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
lavc_opts = hb_encopts_to_dict(job->encoder_options, job->vcodec);
}
+ bit_rate_ceiling = (int64_t)job->width * (int64_t)job->height * (int64_t)fps.num / (int64_t)fps.den;
+
if (job->vquality != HB_INVALID_VIDEO_QUALITY)
{
if ( w->codec_param == AV_CODEC_ID_VP8 ||
@@ -221,7 +256,7 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
//This value was chosen to make the bitrate high enough
//for libvpx to "turn off" the maximum bitrate feature
//that is normally applied to constant quality.
- context->bit_rate = job->width * job->height * fps.num / fps.den;
+ context->bit_rate = bit_rate_ceiling;
}
}
@@ -263,14 +298,16 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
else
{
/* Constant quantizer */
- // These settings produce better image quality than
- // what was previously used
- context->flags |= AV_CODEC_FLAG_QSCALE;
- context->global_quality = FF_QP2LAMBDA * job->vquality + 0.5;
+
//Set constant quality for libvpx
if ( w->codec_param == AV_CODEC_ID_VP8 ||
w->codec_param == AV_CODEC_ID_VP9 )
{
+ // These settings produce better image quality than
+ // what was previously used
+ context->flags |= AV_CODEC_FLAG_QSCALE;
+ context->global_quality = FF_QP2LAMBDA * job->vquality + 0.5;
+
char quality[7];
snprintf(quality, 7, "%.2f", job->vquality);
av_dict_set( &av_opts, "crf", quality, 0 );
@@ -280,8 +317,40 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
context->bit_rate = job->width * job->height * fps.num / fps.den;
hb_log( "encavcodec: encoding at CQ %.2f", job->vquality );
}
+ //Set constant quality for nvenc
+ else if ( job->vcodec == HB_VCODEC_FFMPEG_NVENC_H264 ||
+ job->vcodec == HB_VCODEC_FFMPEG_NVENC_H265 )
+ {
+ char quality[7];
+ snprintf(quality, 7, "%.2f", job->vquality);
+ av_dict_set( &av_opts, "rc", "vbr", 0 );
+ av_dict_set( &av_opts, "cq", quality, 0 );
+
+ // further Advanced Quality Settings in Constant Quality Mode
+ av_dict_set( &av_opts, "init_qpP", "1", 0 );
+ av_dict_set( &av_opts, "init_qpB", "1", 0 );
+ av_dict_set( &av_opts, "init_qpI", "1", 0 );
+ av_dict_set( &av_opts, "rc-lookahead", "16", 0 ); // also adds b-frames (h264 only it seems for now), max 32 causes errors
+ if( job->vcodec == HB_VCODEC_FFMPEG_NVENC_H265 ) {
+ av_dict_set( &av_opts, "spatial_aq", "1", 0 ); // oops, nvenc_hevc.c uses an underscore
+ } else {
+ av_dict_set( &av_opts, "spatial-aq", "1", 0 ); // oops, nvenc_h264.c uses a dash
+ }
+ hb_log( "encavcodec: encoding at rc=vbr CQ %.2f, init_qp 1, rc-lookahead 16, spatial_aq 1, aq-strength default", job->vquality );
+
+ //This value was chosen to make the bitrate high enough
+ //for nvenc to "turn off" the maximum bitrate feature
+ //that is normally applied to constant quality.
+ context->bit_rate = bit_rate_ceiling;
+ hb_log( "encavcodec: bit_rate.4 %ld", context->bit_rate);
+ }
else
{
+ // These settings produce better image quality than
+ // what was previously used
+ context->flags |= AV_CODEC_FLAG_QSCALE;
+ context->global_quality = FF_QP2LAMBDA * job->vquality + 0.5;
+
hb_log( "encavcodec: encoding at constant quantizer %d",
context->global_quality );
}
@@ -841,6 +910,10 @@ static int apply_encoder_preset(int vcodec, AVDictionary ** av_opts,
case HB_VCODEC_FFMPEG_VP8:
case HB_VCODEC_FFMPEG_VP9:
return apply_vpx_preset(av_opts, preset);
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ av_dict_set( av_opts, "preset", preset, 0);
+ break;
default:
break;
}
@@ -860,7 +933,25 @@ const char* const* hb_av_preset_get_names(int encoder)
case HB_VCODEC_FFMPEG_VCE_H265:
return hb_vce_preset_names;
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ return h26x_nvenc_preset_names;
+
default:
return NULL;
}
}
+
+const char* const* hb_av_profile_get_names(int encoder)
+{
+ switch (encoder)
+ {
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ return h264_nvenc_profile_names;
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ return h265_nvenc_profile_names;
+
+ default:
+ return NULL;
+ }
+}
diff --git a/libhb/hbffmpeg.h b/libhb/hbffmpeg.h
index b0aeba8b3..af0476586 100644
--- a/libhb/hbffmpeg.h
+++ b/libhb/hbffmpeg.h
@@ -45,4 +45,9 @@ static const char* const hb_vce_preset_names[] = { "speed", "balanced", "quality
hb_buffer_t * hb_avframe_to_video_buffer(AVFrame *frame, AVRational time_base);
void hb_avframe_set_video_buffer_flags(hb_buffer_t * buf, AVFrame *frame,
AVRational time_base);
+
+int hb_av_encoder_present(int encoder);
+const char* const* hb_av_profile_get_names(int encoder);
+const char* const* hb_av_level_get_names(int encoder);
+
#endif
diff --git a/libhb/module.defs b/libhb/module.defs
index bc760b308..25f9b170c 100644
--- a/libhb/module.defs
+++ b/libhb/module.defs
@@ -86,6 +86,10 @@ ifeq (1,$(FEATURE.vce))
LIBHB.GCC.D += USE_VCE
endif
+ifeq (1,$(FEATURE.nvenc))
+ LIBHB.GCC.D += USE_NVENC
+endif
+
ifeq (1,$(FEATURE.x265))
LIBHB.GCC.D += USE_X265
endif
diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c
index f1053f7ea..65d706565 100644
--- a/libhb/muxavformat.c
+++ b/libhb/muxavformat.c
@@ -208,6 +208,7 @@ static int avformatInit( hb_mux_object_t * m )
case HB_VCODEC_X264_10BIT:
case HB_VCODEC_QSV_H264:
case HB_VCODEC_FFMPEG_VCE_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
track->st->codecpar->codec_id = AV_CODEC_ID_H264;
if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
{
@@ -334,6 +335,7 @@ static int avformatInit( hb_mux_object_t * m )
case HB_VCODEC_QSV_H265:
case HB_VCODEC_QSV_H265_10BIT:
case HB_VCODEC_FFMPEG_VCE_H265:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
track->st->codecpar->codec_id = AV_CODEC_ID_HEVC;
if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets)
{
diff --git a/libhb/nvenc_common.c b/libhb/nvenc_common.c
new file mode 100644
index 000000000..6d1fcead6
--- /dev/null
+++ b/libhb/nvenc_common.c
@@ -0,0 +1,57 @@
+/* nvenc_common.c
+ *
+ * Copyright (c) 2003-2018 HandBrake Team
+ * This file is part of the HandBrake source code.
+ * Homepage: <http://handbrake.fr/>.
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#include "hbffmpeg.h"
+
+#ifdef USE_NVENC
+#include <ffnvcodec/nvEncodeAPI.h>
+#include <ffnvcodec/dynlink_loader.h>
+#endif
+
+int hb_nvenc_h264_available()
+{
+ #ifdef USE_NVENC
+ return hb_check_nvenc_available();
+ #else
+ return 0;
+ #endif
+}
+
+int hb_nvenc_h265_available()
+{
+ #ifdef USE_NVENC
+ return hb_check_nvenc_available();
+ #else
+ return 0;
+ #endif
+}
+
+int hb_check_nvenc_available()
+{
+ #ifdef USE_NVENC
+ uint32_t nvenc_ver;
+ void *context;
+ NvencFunctions *nvenc_dl;
+
+ int loadErr = nvenc_load_functions(&nvenc_dl, context);
+ if (loadErr < 0) {
+ return 0;
+ }
+
+ NVENCSTATUS apiErr = nvenc_dl->NvEncodeAPIGetMaxSupportedVersion(&nvenc_ver);
+ if (apiErr != NV_ENC_SUCCESS)
+ {
+ return 0;
+ }
+
+ return 1;
+ #else
+ return 0;
+ #endif
+}
diff --git a/libhb/nvenc_common.h b/libhb/nvenc_common.h
new file mode 100644
index 000000000..cb58d5489
--- /dev/null
+++ b/libhb/nvenc_common.h
@@ -0,0 +1,11 @@
+/* nvenc_common.h
+ *
+ * Copyright (c) 2003-2018 HandBrake Team
+ * This file is part of the HandBrake source code.
+ * Homepage: <http://handbrake.fr/>.
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+int hb_nvenc_h264_available();
+int hb_nvenc_h265_available();
diff --git a/libhb/work.c b/libhb/work.c
index 1400fee1f..22825840a 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -253,6 +253,17 @@ hb_work_object_t* hb_video_encoder(hb_handle_t *h, int vcodec)
w->codec_param = AV_CODEC_ID_HEVC;
break;
#endif
+#ifdef USE_NVENC
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ w = hb_get_work(h, WORK_ENCAVCODEC);
+ w->codec_param = AV_CODEC_ID_H264;
+ break;
+ case HB_VCODEC_FFMPEG_NVENC_H265:
+ w = hb_get_work(h, WORK_ENCAVCODEC);
+ w->codec_param = AV_CODEC_ID_HEVC;
+ break;
+#endif
+
default:
hb_error("Unknown video codec (0x%x)", vcodec );
}
@@ -486,6 +497,8 @@ void hb_display_job_info(hb_job_t *job)
case HB_VCODEC_QSV_H265_10BIT:
case HB_VCODEC_FFMPEG_VCE_H264:
case HB_VCODEC_FFMPEG_VCE_H265:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
hb_log(" + profile: %s", job->encoder_profile);
default:
break;
@@ -502,6 +515,8 @@ void hb_display_job_info(hb_job_t *job)
case HB_VCODEC_QSV_H265_10BIT:
case HB_VCODEC_FFMPEG_VCE_H264:
case HB_VCODEC_FFMPEG_VCE_H265:
+ case HB_VCODEC_FFMPEG_NVENC_H264:
+ case HB_VCODEC_FFMPEG_NVENC_H265:
hb_log(" + level: %s", job->encoder_level);
default:
break;
diff --git a/make/configure.py b/make/configure.py
index abe6abe47..4ec254fa6 100644
--- a/make/configure.py
+++ b/make/configure.py
@@ -1319,6 +1319,10 @@ def createCLI():
grp.add_option( '--enable-ffmpeg-aac', dest="enable_ffmpeg_aac", default=not host.match( '*-*-darwin*' ), action='store_true', help=h )
grp.add_option( '--disable-ffmpeg-aac', dest="enable_ffmpeg_aac", action='store_false' )
+ h = IfHost( 'enable Nvidia NVEnc video encoder', '*-*-*', none=optparse.SUPPRESS_HELP ).value
+ grp.add_option( '--enable-nvenc', dest="enable_nvenc", default=not host.match( '*-*-darwin*' ), action='store_true', help=h )
+
+
cli.add_option_group( grp )
## add launch options
@@ -1845,6 +1849,7 @@ int main()
doc.add( 'FEATURE.vce', int( options.enable_vce ))
doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode or options.cross) ))
doc.add( 'FEATURE.x265', int( options.enable_x265 ))
+ doc.add( 'FEATURE.nvenc', int( options.enable_nvenc ))
if not Tools.xcodebuild.fail and not options.disable_xcode:
doc.addBlank()
diff --git a/make/include/main.defs b/make/include/main.defs
index dac1985e9..d56b752d4 100644
--- a/make/include/main.defs
+++ b/make/include/main.defs
@@ -70,6 +70,10 @@ ifeq (1,$(FEATURE.vce))
MODULES += contrib/amf
endif
+ifeq (1,$(FEATURE.nvenc))
+ MODULES += contrib/nvenc
+endif
+
ifneq (,$(filter $(BUILD.system),darwin))
MODULES += contrib/xz
endif
diff --git a/test/module.defs b/test/module.defs
index 85b13793d..11ac8a7ff 100644
--- a/test/module.defs
+++ b/test/module.defs
@@ -34,6 +34,10 @@ ifeq (1,$(FEATURE.vce))
TEST.GCC.D += USE_VCE
endif
+ifeq (1,$(FEATURE.nvenc))
+ TEST.GCC.D += USE_NVENC
+endif
+
ifeq (1,$(FEATURE.x265))
TEST.GCC.D += USE_X265
endif
diff --git a/win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs b/win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs
index 65b81c509..8e36dc6c6 100644
--- a/win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs
+++ b/win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs
@@ -415,6 +415,12 @@ namespace HandBrake.Interop.Interop.HbLib
[DllImport("hb", EntryPoint = "hb_vce_h265_available", CallingConvention = CallingConvention.Cdecl)]
public static extern int hb_vce_h265_available();
+ [DllImport("hb", EntryPoint = "hb_nvenc_h264_available", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int hb_nvenc_h264_available();
+
+ [DllImport("hb", EntryPoint = "hb_nvenc_h265_available", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int hb_nvenc_h265_available();
+
// hb_image_t* hb_get_preview2(hb_handle_t* h, int title_idx, int picture, hb_geometry_settings_t* geo, int deinterlace);
[DllImport("hb", EntryPoint = "hb_get_preview2", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr hb_get_preview2(IntPtr hbHandle, int title_idx, int preview_idx, ref hb_geometry_settings_s geo, int deinterlace);
diff --git a/win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs b/win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs
index a5aded796..e8a2ed485 100644
--- a/win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs
+++ b/win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs
@@ -30,8 +30,12 @@ namespace HandBrake.Interop.Interop.Model.Encoding
[DisplayName("H.264 (AMD VCE)")]
[ShortName("vce_h264")]
- VceH264,
+ VceH264,
+ [DisplayName("H.264 (Nvidia NVEnc)")]
+ [ShortName("nvenc_h264")]
+ NvencH264,
+
[DisplayName("MPEG-4")]
[ShortName("mpeg4")]
FFMpeg,
@@ -68,6 +72,10 @@ namespace HandBrake.Interop.Interop.Model.Encoding
[ShortName("vce_h265")]
VceH265,
+ [DisplayName("H.265 (Nvidia NVEnc)")]
+ [ShortName("nvenc_h265")]
+ NvencH265,
+
[DisplayName("VP8")]
[ShortName("VP8")]
VP8,
diff --git a/win/CS/HandBrake.Interop/Utilities/SystemInfo.cs b/win/CS/HandBrake.Interop/Utilities/SystemInfo.cs
index a364c50ac..454132b53 100644
--- a/win/CS/HandBrake.Interop/Utilities/SystemInfo.cs
+++ b/win/CS/HandBrake.Interop/Utilities/SystemInfo.cs
@@ -18,6 +18,9 @@ namespace HandBrake.Interop.Utilities
/// </summary>
public class SystemInfo
{
+ private static bool? isNvencH264Available; // Local cache to prevent log spam.
+ private static bool? isNvencH265Available;
+
/// <summary>
/// Gets a value indicating whether is qsv available.
/// </summary>
@@ -122,5 +125,52 @@ namespace HandBrake.Interop.Utilities
}
}
}
+
+ public static bool IsNVEncH264Available
+ {
+ get
+ {
+ try
+ {
+ if (isNvencH264Available == null)
+ {
+ isNvencH264Available = HBFunctions.hb_nvenc_h264_available() != 0;
+ }
+
+ return isNvencH264Available.Value;
+ }
+ catch (Exception)
+ {
+ // Silent failure. Typically this means the dll hasn't been built with --enable-qsv
+ return false;
+ }
+ }
+ }
+
+ public static bool IsNVEncH265Available
+ {
+ get
+ {
+ try
+ {
+ if (!IsNVEncH264Available)
+ {
+ return false;
+ }
+
+ if (isNvencH265Available == null)
+ {
+ isNvencH265Available = HBFunctions.hb_nvenc_h265_available() != 0;
+ }
+
+ return isNvencH265Available.Value;
+ }
+ catch (Exception)
+ {
+ // Silent failure. Typically this means the dll hasn't been built with --enable-qsv
+ return false;
+ }
+ }
+ }
}
}
diff --git a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
index 42ccf1c10..40131ddb3 100644
--- a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
@@ -101,6 +101,16 @@ namespace HandBrakeWPF.Converters.Video
encoders.Remove(VideoEncoder.VceH265);
}
+ if (!SystemInfo.IsNVEncH264Available)
+ {
+ encoders.Remove(VideoEncoder.NvencH264);
+ }
+
+ if (!SystemInfo.IsNVEncH265Available)
+ {
+ encoders.Remove(VideoEncoder.NvencH265);
+ }
+
return EnumHelper<VideoEncoder>.GetEnumDisplayValuesSubset(encoders);
}
diff --git a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
index 4bd5b777d..74ac53a85 100644
--- a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
@@ -349,6 +349,8 @@ namespace HandBrakeWPF.ViewModels
case VideoEncoder.QuickSyncH265:
case VideoEncoder.VceH264:
case VideoEncoder.VceH265:
+ case VideoEncoder.NvencH264:
+ case VideoEncoder.NvencH265:
rfValue = 51.0 - value;
rfValue = Math.Round(rfValue, 0);
this.Task.Quality = rfValue;
@@ -977,7 +979,8 @@ namespace HandBrakeWPF.ViewModels
if (preset.Task.VideoEncoder == VideoEncoder.X264 || preset.Task.VideoEncoder == VideoEncoder.X264_10
|| preset.Task.VideoEncoder == VideoEncoder.X265 || preset.Task.VideoEncoder == VideoEncoder.X265_10 || preset.Task.VideoEncoder == VideoEncoder.X265_12
|| preset.Task.VideoEncoder == VideoEncoder.QuickSync || preset.Task.VideoEncoder == VideoEncoder.QuickSyncH265 || preset.Task.VideoEncoder == VideoEncoder.QuickSyncH26510b
- || preset.Task.VideoEncoder == VideoEncoder.VceH264 || preset.Task.VideoEncoder == VideoEncoder.VceH265)
+ || preset.Task.VideoEncoder == VideoEncoder.VceH264 || preset.Task.VideoEncoder == VideoEncoder.VceH265
+ || preset.Task.VideoEncoder == VideoEncoder.NvencH264 || preset.Task.VideoEncoder == VideoEncoder.NvencH265)
{
this.VideoLevel = preset.Task.VideoLevel != null ? preset.Task.VideoLevel.Clone() : this.VideoLevels.FirstOrDefault();
this.VideoProfile = preset.Task.VideoProfile != null ? preset.Task.VideoProfile.Clone() : this.VideoProfiles.FirstOrDefault();
@@ -1090,7 +1093,8 @@ namespace HandBrakeWPF.ViewModels
|| this.Task.VideoEncoder == VideoEncoder.X265 || this.Task.VideoEncoder == VideoEncoder.X265_10
|| this.Task.VideoEncoder == VideoEncoder.X265_12 || this.Task.VideoEncoder == VideoEncoder.QuickSync
|| this.Task.VideoEncoder == VideoEncoder.QuickSyncH265 || this.Task.VideoEncoder == VideoEncoder.QuickSyncH26510b
- || this.Task.VideoEncoder == VideoEncoder.VceH264 || this.Task.VideoEncoder == VideoEncoder.VceH265)
+ || this.Task.VideoEncoder == VideoEncoder.VceH264 || this.Task.VideoEncoder == VideoEncoder.VceH265
+ || this.Task.VideoEncoder == VideoEncoder.NvencH264 || this.Task.VideoEncoder == VideoEncoder.NvencH265)
{
if (!Equals(preset.Task.VideoPreset, this.Task.VideoPreset))
{
@@ -1183,6 +1187,8 @@ namespace HandBrakeWPF.ViewModels
case VideoEncoder.QuickSyncH265:
case VideoEncoder.VceH264:
case VideoEncoder.VceH265:
+ case VideoEncoder.NvencH264:
+ case VideoEncoder.NvencH265:
this.QualityMin = 0;
this.QualityMax = 51;
break;
@@ -1317,9 +1323,12 @@ namespace HandBrakeWPF.ViewModels
case VideoEncoder.QuickSyncH26510b:
case VideoEncoder.VceH264:
case VideoEncoder.VceH265:
+ case VideoEncoder.NvencH264:
+ case VideoEncoder.NvencH265:
if (this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b
- || this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265)
+ || this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265
+ || this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265)
{
cqStep = 1;
}
@@ -1441,12 +1450,15 @@ namespace HandBrakeWPF.ViewModels
// Update control display
this.UseAdvancedTab = selectedEncoder != VideoEncoder.QuickSync && selectedEncoder != VideoEncoder.QuickSyncH265 && selectedEncoder != VideoEncoder.QuickSyncH26510b
- && selectedEncoder != VideoEncoder.VceH264 && selectedEncoder != VideoEncoder.VceH265 && this.UseAdvancedTab;
+ && selectedEncoder != VideoEncoder.VceH264 && selectedEncoder != VideoEncoder.VceH265
+ && selectedEncoder != VideoEncoder.NvencH264 && selectedEncoder != VideoEncoder.NvencH265
+ && this.UseAdvancedTab;
this.DisplayOptimiseOptions = this.SelectedVideoEncoder == VideoEncoder.X264 || this.SelectedVideoEncoder == VideoEncoder.X264_10 ||
this.SelectedVideoEncoder == VideoEncoder.X265 || this.SelectedVideoEncoder == VideoEncoder.X265_10 || this.SelectedVideoEncoder == VideoEncoder.X265_12 ||
this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b ||
this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265 ||
+ this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265 ||
this.SelectedVideoEncoder == VideoEncoder.VP8 || this.SelectedVideoEncoder == VideoEncoder.VP9;
this.DisplayNonQSVControls = this.SelectedVideoEncoder != VideoEncoder.QuickSync && this.SelectedVideoEncoder != VideoEncoder.QuickSyncH265 && this.SelectedVideoEncoder != VideoEncoder.QuickSyncH26510b;
@@ -1459,7 +1471,8 @@ namespace HandBrakeWPF.ViewModels
this.DisplayLevelControl = this.SelectedVideoEncoder == VideoEncoder.X264 || this.SelectedVideoEncoder == VideoEncoder.X264_10 ||
this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b ||
- this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265;
+ this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265 ||
+ this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265;
this.DisplayProfileControl = this.SelectedVideoEncoder == VideoEncoder.X264
|| this.SelectedVideoEncoder == VideoEncoder.X264_10
@@ -1470,7 +1483,9 @@ namespace HandBrakeWPF.ViewModels
|| this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265
|| this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b
|| this.SelectedVideoEncoder == VideoEncoder.VceH264
- || this.SelectedVideoEncoder == VideoEncoder.VceH265;
+ || this.SelectedVideoEncoder == VideoEncoder.VceH265
+ || this.SelectedVideoEncoder == VideoEncoder.NvencH264
+ || this.SelectedVideoEncoder == VideoEncoder.NvencH265;
// Refresh Display
this.NotifyOfPropertyChange(() => this.Rfqp);