diff options
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/common.c | 81 | ||||
-rw-r--r-- | libhb/common.h | 8 | ||||
-rw-r--r-- | libhb/encavcodec.c | 109 | ||||
-rw-r--r-- | libhb/hbffmpeg.h | 5 | ||||
-rw-r--r-- | libhb/module.defs | 4 | ||||
-rw-r--r-- | libhb/muxavformat.c | 2 | ||||
-rw-r--r-- | libhb/nvenc_common.c | 57 | ||||
-rw-r--r-- | libhb/nvenc_common.h | 11 | ||||
-rw-r--r-- | libhb/work.c | 15 |
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; |