]> granicus.if.org Git - handbrake/commitdiff
Add NVEnc encoder. (Round 3) (#1437)
authorScott <628593+sr55@users.noreply.github.com>
Fri, 29 Jun 2018 18:48:26 +0000 (19:48 +0100)
committerGitHub <noreply@github.com>
Fri, 29 Jun 2018 18:48:26 +0000 (19:48 +0100)
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.

20 files changed:
contrib/ffmpeg/module.defs
contrib/nvenc/module.defs [new file with mode: 0644]
contrib/nvenc/module.rules [new file with mode: 0644]
libhb/common.c
libhb/common.h
libhb/encavcodec.c
libhb/hbffmpeg.h
libhb/module.defs
libhb/muxavformat.c
libhb/nvenc_common.c [new file with mode: 0644]
libhb/nvenc_common.h [new file with mode: 0644]
libhb/work.c
make/configure.py
make/include/main.defs
test/module.defs
win/CS/HandBrake.Interop/Interop/HbLib/HbFunctions.cs
win/CS/HandBrake.Interop/Interop/Model/Encoding/VideoEncoder.cs
win/CS/HandBrake.Interop/Utilities/SystemInfo.cs
win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs

index 63924ad960ccd6e59d69b3d4c5ec46afd4c5ae7f..e24a897b9d6d62a7f36bf546c0c9453d60a4990c 100644 (file)
@@ -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 (file)
index 0000000..e040b9a
--- /dev/null
@@ -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 (file)
index 0000000..976986a
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,NVENC))
+$(eval $(call import.CONTRIB.rules,NVENC))
index a4c84198f4fa1e70a0a1b5be5fbb7cb1b30e6368..e8a1dee9fa3553d457bd4dc03d04092b6589384f 100644 (file)
 #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;
index a91d608c97b1ea617f0280a04de0a075932fc5cf..1d28ada4cf30570f7115221f594caf3e0b4cd2bc 100644 (file)
@@ -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.)
index ee914faba15c20ac09776af3c3aff9ea7f6f4edf..17a6fdb257e2858fb13dff509de990472fc57262 100644 (file)
@@ -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;
+     }
+}
index b0aeba8b3b6fa5cdc5e514c88dc0ba406a682683..af04765865ea7f798ddf5e016b52e8a054179d9f 100644 (file)
@@ -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
index bc760b3084558aec6918d7126572a67b197bf6a9..25f9b170ca0a63fba2f93152c101c9ada44c48cf 100644 (file)
@@ -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
index f1053f7eadb22ffe65d93d0b38a46c734a88d060..65d70656585cddd64efb8a463f522381ee85bcc7 100644 (file)
@@ -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 (file)
index 0000000..6d1fcea
--- /dev/null
@@ -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 (file)
index 0000000..cb58d54
--- /dev/null
@@ -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();
index 1400fee1f07195c33b347082e44555077586a4fc..22825840a67345e881f2c8924aa3ea7c631de7f8 100644 (file)
@@ -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;
index abe6abe478cc65150d1f966652e6428f97572b1a..4ec254fa66d9cfc4afcc762726ccef83f602928a 100644 (file)
@@ -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()
index dac1985e919d54b496ec0e6623c966e842a7ad59..d56b752d4d561eef8fd67f9d7279c7af49c03757 100644 (file)
@@ -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
index 85b13793d1666b985953f804156ef0cbd2c57b01..11ac8a7fff84f6aa6cc94f1747ef829a13942048 100644 (file)
@@ -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
index 65b81c50935afdbd4785969f24f25876a3aae0bb..8e36dc6c6868f0ac1cafe13b0e78bea1451012cc 100644 (file)
@@ -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);
index a5aded796ea726818f935cd27e0d34fa9d58ca75..e8a2ed485e8672f710a54cea59808dfed9d34c7e 100644 (file)
@@ -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,
index a364c50ac3452ebffaaabc7d4df395420b37d3e0..454132b53319ecd4739625dc00a6b39a8e41737a 100644 (file)
@@ -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;
+                }
+            }
+        }
     }
 }
index 42ccf1c10048c364a2621fff6f14e4f74941a003..40131ddb3ecb18ba99a72e994f8cabf6b03b2a8f 100644 (file)
@@ -101,6 +101,16 @@ namespace HandBrakeWPF.Converters.Video
                     encoders.Remove(VideoEncoder.VceH265);\r
                 }\r
 \r
+                if (!SystemInfo.IsNVEncH264Available)\r
+                {\r
+                    encoders.Remove(VideoEncoder.NvencH264);\r
+                }\r
+\r
+                if (!SystemInfo.IsNVEncH265Available)\r
+                {\r
+                    encoders.Remove(VideoEncoder.NvencH265);\r
+                }\r
+\r
                 return EnumHelper<VideoEncoder>.GetEnumDisplayValuesSubset(encoders);\r
             }\r
 \r
index 4bd5b777d42efa78580e0b7d352a33cdde2b12e5..74ac53a8530f0fa9892fb0f1bc8362059b46b7bb 100644 (file)
@@ -349,6 +349,8 @@ namespace HandBrakeWPF.ViewModels
                     case VideoEncoder.QuickSyncH265:\r
                     case VideoEncoder.VceH264:\r
                     case VideoEncoder.VceH265:\r
+                    case VideoEncoder.NvencH264:\r
+                    case VideoEncoder.NvencH265:\r
                         rfValue = 51.0 - value;\r
                         rfValue = Math.Round(rfValue, 0);\r
                         this.Task.Quality = rfValue;\r
@@ -977,7 +979,8 @@ namespace HandBrakeWPF.ViewModels
                 if (preset.Task.VideoEncoder == VideoEncoder.X264 || preset.Task.VideoEncoder == VideoEncoder.X264_10\r
                     || preset.Task.VideoEncoder == VideoEncoder.X265 || preset.Task.VideoEncoder == VideoEncoder.X265_10 || preset.Task.VideoEncoder == VideoEncoder.X265_12\r
                     || preset.Task.VideoEncoder == VideoEncoder.QuickSync || preset.Task.VideoEncoder == VideoEncoder.QuickSyncH265 || preset.Task.VideoEncoder == VideoEncoder.QuickSyncH26510b\r
-                    || preset.Task.VideoEncoder == VideoEncoder.VceH264 || preset.Task.VideoEncoder == VideoEncoder.VceH265)\r
+                    || preset.Task.VideoEncoder == VideoEncoder.VceH264 || preset.Task.VideoEncoder == VideoEncoder.VceH265\r
+                    || preset.Task.VideoEncoder == VideoEncoder.NvencH264 || preset.Task.VideoEncoder == VideoEncoder.NvencH265)\r
                 {\r
                     this.VideoLevel = preset.Task.VideoLevel != null ? preset.Task.VideoLevel.Clone() : this.VideoLevels.FirstOrDefault();\r
                     this.VideoProfile = preset.Task.VideoProfile != null ? preset.Task.VideoProfile.Clone() : this.VideoProfiles.FirstOrDefault();\r
@@ -1090,7 +1093,8 @@ namespace HandBrakeWPF.ViewModels
                 || this.Task.VideoEncoder == VideoEncoder.X265 || this.Task.VideoEncoder == VideoEncoder.X265_10\r
                 || this.Task.VideoEncoder == VideoEncoder.X265_12 || this.Task.VideoEncoder == VideoEncoder.QuickSync\r
                 || this.Task.VideoEncoder == VideoEncoder.QuickSyncH265 || this.Task.VideoEncoder == VideoEncoder.QuickSyncH26510b\r
-                || this.Task.VideoEncoder == VideoEncoder.VceH264 || this.Task.VideoEncoder == VideoEncoder.VceH265)\r
+                || this.Task.VideoEncoder == VideoEncoder.VceH264 || this.Task.VideoEncoder == VideoEncoder.VceH265\r
+                || this.Task.VideoEncoder == VideoEncoder.NvencH264 || this.Task.VideoEncoder == VideoEncoder.NvencH265)\r
             {\r
                 if (!Equals(preset.Task.VideoPreset, this.Task.VideoPreset))\r
                 {\r
@@ -1183,6 +1187,8 @@ namespace HandBrakeWPF.ViewModels
                 case VideoEncoder.QuickSyncH265:\r
                 case VideoEncoder.VceH264:\r
                 case VideoEncoder.VceH265:\r
+                case VideoEncoder.NvencH264:\r
+                case VideoEncoder.NvencH265:\r
                     this.QualityMin = 0;\r
                     this.QualityMax = 51;\r
                     break;\r
@@ -1317,9 +1323,12 @@ namespace HandBrakeWPF.ViewModels
                 case VideoEncoder.QuickSyncH26510b:\r
                 case VideoEncoder.VceH264:\r
                 case VideoEncoder.VceH265:\r
+                case VideoEncoder.NvencH264:\r
+                case VideoEncoder.NvencH265:\r
 \r
                     if (this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b\r
-                        || this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265)\r
+                        || this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265\r
+                        || this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265)\r
                     {\r
                         cqStep = 1;\r
                     }\r
@@ -1441,12 +1450,15 @@ namespace HandBrakeWPF.ViewModels
 \r
             // Update control display\r
             this.UseAdvancedTab = selectedEncoder != VideoEncoder.QuickSync && selectedEncoder != VideoEncoder.QuickSyncH265 && selectedEncoder != VideoEncoder.QuickSyncH26510b\r
-                               && selectedEncoder != VideoEncoder.VceH264 && selectedEncoder != VideoEncoder.VceH265  && this.UseAdvancedTab;\r
+                               && selectedEncoder != VideoEncoder.VceH264 && selectedEncoder != VideoEncoder.VceH265\r
+                               && selectedEncoder != VideoEncoder.NvencH264 && selectedEncoder != VideoEncoder.NvencH265\r
+                               && this.UseAdvancedTab;\r
 \r
             this.DisplayOptimiseOptions = this.SelectedVideoEncoder == VideoEncoder.X264 || this.SelectedVideoEncoder == VideoEncoder.X264_10 ||\r
                                           this.SelectedVideoEncoder == VideoEncoder.X265 || this.SelectedVideoEncoder == VideoEncoder.X265_10 || this.SelectedVideoEncoder == VideoEncoder.X265_12 ||\r
                                           this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b ||\r
                                           this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265 ||\r
+                                          this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265 ||\r
                                           this.SelectedVideoEncoder == VideoEncoder.VP8 || this.SelectedVideoEncoder == VideoEncoder.VP9;\r
 \r
             this.DisplayNonQSVControls = this.SelectedVideoEncoder != VideoEncoder.QuickSync && this.SelectedVideoEncoder != VideoEncoder.QuickSyncH265 && this.SelectedVideoEncoder != VideoEncoder.QuickSyncH26510b;\r
@@ -1459,7 +1471,8 @@ namespace HandBrakeWPF.ViewModels
 \r
             this.DisplayLevelControl = this.SelectedVideoEncoder == VideoEncoder.X264 || this.SelectedVideoEncoder == VideoEncoder.X264_10 || \r
                                        this.SelectedVideoEncoder == VideoEncoder.QuickSync || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265 || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b ||\r
-                                       this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265;\r
+                                       this.SelectedVideoEncoder == VideoEncoder.VceH264 || this.SelectedVideoEncoder == VideoEncoder.VceH265 ||\r
+                                       this.SelectedVideoEncoder == VideoEncoder.NvencH264 || this.SelectedVideoEncoder == VideoEncoder.NvencH265;\r
 \r
             this.DisplayProfileControl = this.SelectedVideoEncoder == VideoEncoder.X264\r
                                          || this.SelectedVideoEncoder == VideoEncoder.X264_10\r
@@ -1470,7 +1483,9 @@ namespace HandBrakeWPF.ViewModels
                                          || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH265\r
                                          || this.SelectedVideoEncoder == VideoEncoder.QuickSyncH26510b\r
                                          || this.SelectedVideoEncoder == VideoEncoder.VceH264\r
-                                         || this.SelectedVideoEncoder == VideoEncoder.VceH265;\r
+                                         || this.SelectedVideoEncoder == VideoEncoder.VceH265\r
+                                         || this.SelectedVideoEncoder == VideoEncoder.NvencH264\r
+                                         || this.SelectedVideoEncoder == VideoEncoder.NvencH265;\r
 \r
             // Refresh Display\r
             this.NotifyOfPropertyChange(() => this.Rfqp);\r