0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

libobs: Defer reconfiguring encoders to the encode threads

Fixes a long-standing issue with Dynamic Bitrate where the RTMP output
thread could try to reconfigure an encoder while the encoder is in the
middle of encoding. x264 seems to handle multithreaded calls well, but
NVENC would deadlock in this situation with no error visible to the
user.
This commit is contained in:
Richard Stanway 2021-08-21 21:27:45 +02:00 committed by Jim
parent 1444ead812
commit 4772a99e3e
3 changed files with 21 additions and 3 deletions

View File

@ -397,9 +397,12 @@ void obs_encoder_update(obs_encoder_t *encoder, obs_data_t *settings)
obs_data_apply(encoder->context.settings, settings);
if (encoder->info.update && encoder->context.data)
encoder->info.update(encoder->context.data,
encoder->context.settings);
// Note, we don't actually apply the changes to the encoder here
// as it may be active in another thread. Setting this to true
// makes the changes apply at the next possible moment in the
// encoder / GPU encoder thread.
if (encoder->info.update)
encoder->reconfigure_requested = true;
}
bool obs_encoder_get_extra_data(const obs_encoder_t *encoder,
@ -970,6 +973,12 @@ bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame)
bool received = false;
bool success;
if (encoder->reconfigure_requested) {
encoder->reconfigure_requested = false;
encoder->info.update(encoder->context.data,
encoder->context.settings);
}
pkt.timebase_num = encoder->timebase_num;
pkt.timebase_den = encoder->timebase_den;
pkt.encoder = encoder;

View File

@ -1120,6 +1120,9 @@ struct obs_encoder {
const char *profile_encoder_encode_name;
char *last_error_message;
/* reconfigure encoder at next possible opportunity */
bool reconfigure_requested;
};
extern struct obs_encoder_info *find_encoder(const char *id);

View File

@ -90,6 +90,12 @@ static void *gpu_encode_thread(void *unused)
if (video_pause_check(&encoder->pause, timestamp))
continue;
if (encoder->reconfigure_requested) {
encoder->reconfigure_requested = false;
encoder->info.update(encoder->context.data,
encoder->context.settings);
}
if (!encoder->start_ts)
encoder->start_ts = timestamp;