Skip to content

Commit

Permalink
Nvidia NVENC configuration
Browse files Browse the repository at this point in the history
- configuration
  - nvenc_preset
  - nvenc_delay
  - nvenc_zerolatency
- documentation

This is minimum to have control over encoder and minimize latency.

To minimize latency:
- set preset to ll, llhq or llhp
- set nvenc_delay to -1 (maps to 0)
- set nvenc_zerolatency to 1

Closes #37
  • Loading branch information
bmegli committed Jan 17, 2023
1 parent 6fdc9e0 commit 67447a1
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
10 changes: 8 additions & 2 deletions examples/hve_encode_raw_h264.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[]);
Expand All @@ -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
Expand Down
9 changes: 7 additions & 2 deletions examples/hve_encode_raw_hevc10.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[]);
Expand All @@ -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
Expand Down
13 changes: 11 additions & 2 deletions hve.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 21 additions & 0 deletions hve.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,24 @@ struct hve;
* For the details on loading HuC see:
* <a href="https://github.com/bmegli/hardware-video-encoder/wiki/GuC-and-HuC">Loading GuC and HuC</a>
*
* 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
Expand All @@ -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
};

/**
Expand Down

0 comments on commit 67447a1

Please sign in to comment.