obs-ffmpeg: NVENC usage fixes

Only use lossless encode if the capability is supported.

Set qpPrimeYZeroTransformBypassFlag to 1 for lossless.

Do not set profileGUID for lossless.

For both NVENC implementations, retry with a heavier reset because both
are unable to recover from failure lightly.
This commit is contained in:
jpark37
2021-06-07 02:23:46 -07:00
committed by Jim
parent 4d647d8d15
commit a8414a09cc
2 changed files with 78 additions and 50 deletions

View File

@@ -102,13 +102,6 @@ static bool nvenc_init_codec(struct nvenc_encoder *enc, bool psycho_aq)
}
ret = avcodec_open2(enc->context, enc->nvenc, NULL);
if ((ret < 0) && psycho_aq) {
warn("avcodec_open2 failed, "
"trying again without Psycho Visual Tuning");
set_psycho_aq(enc, false);
ret = avcodec_open2(enc->context, enc->nvenc, NULL);
}
if (ret < 0) {
// if we were a fallback from jim-nvenc, there may already be a
// more useful error returned from that, so don't overwrite.
@@ -173,10 +166,9 @@ static bool nvenc_init_codec(struct nvenc_encoder *enc, bool psycho_aq)
enum RC_MODE { RC_MODE_CBR, RC_MODE_VBR, RC_MODE_CQP, RC_MODE_LOSSLESS };
static bool nvenc_update(void *data, obs_data_t *settings)
static bool nvenc_update(struct nvenc_encoder *enc, obs_data_t *settings,
bool psycho_aq)
{
struct nvenc_encoder *enc = data;
const char *rc = obs_data_get_string(settings, "rate_control");
int bitrate = (int)obs_data_get_int(settings, "bitrate");
int cqp = (int)obs_data_get_int(settings, "cqp");
@@ -186,7 +178,6 @@ static bool nvenc_update(void *data, obs_data_t *settings)
int gpu = (int)obs_data_get_int(settings, "gpu");
bool cbr_override = obs_data_get_bool(settings, "cbr");
int bf = (int)obs_data_get_int(settings, "bf");
bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
video_t *video = obs_encoder_video(enc->encoder);
const struct video_output_info *voi = video_output_get_info(video);
@@ -357,7 +348,8 @@ static void nvenc_destroy(void *data)
bfree(enc);
}
static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
static void *nvenc_create_internal(obs_data_t *settings, obs_encoder_t *encoder,
bool psycho_aq)
{
struct nvenc_encoder *enc;
@@ -387,7 +379,7 @@ static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
goto fail;
}
if (!nvenc_update(enc, settings))
if (!nvenc_update(enc, settings, psycho_aq))
goto fail;
return enc;
@@ -397,6 +389,18 @@ fail:
return NULL;
}
static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
{
bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
void *enc = nvenc_create_internal(settings, encoder, psycho_aq);
if ((enc == NULL) && psycho_aq) {
blog(LOG_WARNING,
"[NVENC encoder] nvenc_create_internal failed, "
"trying again without Psycho Visual Tuning");
enc = nvenc_create_internal(settings, encoder, false);
}
}
static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame,
int height, enum AVPixelFormat format)
{