diff --git a/README.md b/README.md index 9c99b71..f085a75 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,9 @@ There are just 4 functions and 3 user-visible data types: ```C struct hve_config hardware_config = {WIDTH, HEIGHT, INPUT_WIDTH, INPUT_HEIGHT, FRAMERATE, DEVICE, ENCODER, PIXEL_FORMAT, PROFILE, BFRAMES, - BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, VAAPI_LOW_POWER}; + BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, + VAAPI_LOW_POWER + NVENC_PRESET, NVENC_DELAY, NVENC_ZEROLATENCY}; struct hve *hardware_encoder=hve_init(&hardware_config); struct hve_frame frame = { 0 }; diff --git a/examples/hve_encode_raw_h264.c b/examples/hve_encode_raw_h264.c index 2ea9ca9..1b4a2a2 100644 --- a/examples/hve_encode_raw_h264.c +++ b/examples/hve_encode_raw_h264.c @@ -28,8 +28,11 @@ const int BFRAMES=0; //max_b_frames, set to 0 to minimize latency, non-zero to m const int BITRATE=0; //average bitrate in VBR mode (bit_rate != 0 and qp == 0) const int QP=0; //quantization parameter in CQP mode (qp != 0 and bit_rate == 0) const int GOP_SIZE=0; //group of pictures size, 0 for default (determines keyframe period) -const int COMPRESSION_LEVEL=0; //speed-quality tradeoff, 0 for default, 1 for the highest quality, 7 for the fastest +const int COMPRESSION_LEVEL=0; //encoder/codec dependent, 0 for default, for VAAPI 1-7 speed-quality tradeoff, 1 highest quality, 7 fastest const int VAAPI_LOW_POWER=0; //alternative VAAPI limited low-power encoding path if non-zero +const char *NVENC_PRESET=NULL; //NVENC and codec specific, NULL / "" or like "default", "slow", "medium", "fast", "hp", "hq", "bd", "ll", "llhq", "llhp", "lossless", "losslesshp" +const int NVENC_DELAY=0; //NVENC specific delay of frame output, 0 for default, -1 for 0 or positive value, set -1 to minimize latency +const int NVENC_ZEROLATENCY=0; //NVENC specific no reordering delay if non-zero, enable to minimize latency int encoding_loop(struct hve *hardware_encoder, FILE *output_file); int process_user_input(int argc, char* argv[]); @@ -45,7 +48,10 @@ int main(int argc, char* argv[]) //prepare library data struct hve_config hardware_config = {WIDTH, HEIGHT, INPUT_WIDTH, INPUT_HEIGHT, FRAMERATE, DEVICE, ENCODER, PIXEL_FORMAT, PROFILE, BFRAMES, - BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, VAAPI_LOW_POWER}; + BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, + VAAPI_LOW_POWER, + NVENC_PRESET, NVENC_DELAY, NVENC_ZEROLATENCY}; + struct hve *hardware_encoder; //prepare file for raw H.264 output diff --git a/examples/hve_encode_raw_hevc10.c b/examples/hve_encode_raw_hevc10.c index 4aa9b64..5a30c67 100644 --- a/examples/hve_encode_raw_hevc10.c +++ b/examples/hve_encode_raw_hevc10.c @@ -28,8 +28,11 @@ const int BFRAMES=0; //max_b_frames, set to 0 to minimize latency, non-zero to m const int BITRATE=0; //average bitrate in VBR mode (bit_rate != 0 and qp == 0) const int QP=0; //quantization parameter in CQP mode (qp != 0 and bit_rate == 0) const int GOP_SIZE=0; //group of pictures size, 0 for default (determines keyframe period) -const int COMPRESSION_LEVEL=0; //speed-quality tradeoff, 0 for default, 1 for the highest quality, 7 for the fastest +const int COMPRESSION_LEVEL=0; //encoder/codec dependent, 0 for default, for VAAPI 1-7 speed-quality tradeoff, 1 highest quality, 7 fastest const int VAAPI_LOW_POWER=0; //alternative VAAPI limited low-power encoding path if non-zero +const char *NVENC_PRESET=NULL; //NVENC and codec specific, NULL / "" or like "default", "slow", "medium", "fast", "hp", "hq", "bd", "ll", "llhq", "llhp", "lossless", "losslesshp" +const int NVENC_DELAY=0; //NVENC specific delay of frame output, 0 for default, -1 for 0 or positive value, set -1 to minimize latency +const int NVENC_ZEROLATENCY=0; //NVENC specific no reordering delay if non-zero, enable to minimize latency int encoding_loop(struct hve *hardware_encoder, FILE *output_file); int process_user_input(int argc, char* argv[]); @@ -45,7 +48,9 @@ int main(int argc, char* argv[]) //prepare library data struct hve_config hardware_config = {WIDTH, HEIGHT, INPUT_WIDTH, INPUT_HEIGHT, FRAMERATE, DEVICE, ENCODER, PIXEL_FORMAT, PROFILE, BFRAMES, - BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, VAAPI_LOW_POWER}; + BITRATE, QP, GOP_SIZE, COMPRESSION_LEVEL, + VAAPI_LOW_POWER, + NVENC_PRESET, NVENC_DELAY, NVENC_ZEROLATENCY}; struct hve *hardware_encoder; //prepare file for raw HEVC output diff --git a/hve.c b/hve.c index 7665637..0bbe9fa 100644 --- a/hve.c +++ b/hve.c @@ -128,12 +128,21 @@ struct hve *hve_init(const struct hve_config *config) AVDictionary *opts = NULL; - if(config->qp && av_dict_set_int(&opts, "qp", config->qp, 0) < 0) + if(config->qp && (av_dict_set_int(&opts, "qp", config->qp, 0) < 0)) return hve_close_and_return_null(h, "failed to initialize option dictionary (qp)"); - if(config->vaapi_low_power && av_dict_set_int(&opts, "low_power", config->vaapi_low_power != 0, 0) < 0) + if(config->vaapi_low_power && (av_dict_set_int(&opts, "low_power", config->vaapi_low_power != 0, 0) < 0)) return hve_close_and_return_null(h, "failed to initialize option dictionary (low_power)"); + if(config->nvenc_preset && config->nvenc_preset[0] != '\0' && (av_dict_set(&opts, "preset", config->nvenc_preset, 0) < 0)) + return hve_close_and_return_null(h, "failed to initialize option dictionary (NVENC preset)"); + + if(config->nvenc_delay && (av_dict_set_int(&opts, "delay", (config->nvenc_delay > 0) ? config->nvenc_delay : 0, 0) < 0)) + return hve_close_and_return_null(h, "failed to initialize option dictionary (NVENC delay)"); + + if(config->nvenc_zerolatency && (av_dict_set_int(&opts, "zerolatency", config->nvenc_zerolatency != 0 , 0) < 0)) + return hve_close_and_return_null(h, "failed to initialize option dictionary (NVENC zerolatency)"); + if((err = avcodec_open2(h->avctx, codec, &opts)) < 0) { av_dict_free(&opts); diff --git a/hve.h b/hve.h index 3c20ba7..9306ff2 100644 --- a/hve.h +++ b/hve.h @@ -156,6 +156,24 @@ struct hve; * For the details on loading HuC see: * Loading GuC and HuC * + * The nvenc_preset is encoding preset to use, may be codec specific. + * + * The default is medium ("default", "" or NULL string) + * + * Typicall values: "default", "slow", "medium", "fast", "hp", "hq", "bd", "ll", "llhq", "llhp", "lossless", "losslesshp" + * + * You may check available presets (H.264 example) + * @code + * ffmpeg -h encoder=h264_nvenc -hide_banner + * @endcode + * + * The nvenc_delay is delay for frame output by given amount of frames. + * 0 leaves defaults (which is INT_MAX in FFmpeg nvenc), -1 sets 0. + * Set to -1 (maps to 0) if you explicitly need low latency. + * + * The nvenc_zerolatency is NVENC specific for no reordering delay. + * Set to non-zero if you need low latency. + * * @see hve_init */ struct hve_config @@ -175,6 +193,9 @@ struct hve_config int gop_size; //!< group of pictures size, 0 for default, -1 for intra only int compression_level; //!< encoder/codec dependent, 0 for default, for VAAPI 1-7 speed-quality tradeoff, 1 highest quality, 7 fastest int vaapi_low_power; //!< VAAPI specific alternative limited low-power encoding if non-zero + const char *nvenc_preset; //!< NVENC and codec specific, NULL / "" or like "default", "slow", "medium", "fast", "hp", "hq", "bd", "ll", "llhq", "llhp", "lossless", "losslesshp" + int nvenc_delay; //NVENC specific delay of frame output, 0 for default, -1 for 0 or positive value, set -1 to minimize latency + int nvenc_zerolatency; //NVENC specific no reordering delay if non-zero, enable to minimize latency }; /**