summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
Diffstat (limited to 'libhb')
-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
9 files changed, 249 insertions, 43 deletions
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;