libobs: Switch to full reference counting for encoders

Removes the "destroy_on_stop" hack that predates refcounting.
Ensures outputs hold strong references to all their encoders.
This commit is contained in:
derrod
2024-08-12 03:50:36 +02:00
committed by Lain
parent 3312c2567d
commit 2c57f4564c
3 changed files with 17 additions and 34 deletions

View File

@@ -386,7 +386,7 @@ static inline void free_audio_buffers(struct obs_encoder *encoder)
}
}
static void obs_encoder_actually_destroy(obs_encoder_t *encoder)
void obs_encoder_destroy(obs_encoder_t *encoder)
{
if (encoder) {
pthread_mutex_lock(&encoder->outputs_mutex);
@@ -427,28 +427,6 @@ static void obs_encoder_actually_destroy(obs_encoder_t *encoder)
}
}
/* does not actually destroy the encoder until all connections to it have been
* removed. (full reference counting really would have been superfluous) */
void obs_encoder_destroy(obs_encoder_t *encoder)
{
if (encoder) {
bool destroy;
obs_context_data_remove(&encoder->context);
pthread_mutex_lock(&encoder->init_mutex);
pthread_mutex_lock(&encoder->callbacks_mutex);
destroy = encoder->callbacks.num == 0;
if (!destroy)
encoder->destroy_on_stop = true;
pthread_mutex_unlock(&encoder->callbacks_mutex);
pthread_mutex_unlock(&encoder->init_mutex);
if (destroy)
obs_encoder_actually_destroy(encoder);
}
}
const char *obs_encoder_get_name(const obs_encoder_t *encoder)
{
return obs_encoder_valid(encoder, "obs_encoder_get_name")
@@ -823,9 +801,6 @@ void obs_encoder_stop(obs_encoder_t *encoder,
struct obs_encoder_group *group = encoder->encoder_group;
if (encoder->destroy_on_stop)
obs_encoder_actually_destroy(encoder);
/* Destroying the group all the way back here prevents a race
* where destruction of the group can prematurely destroy the
* encoder within internal functions. This is the point where it

View File

@@ -1326,8 +1326,6 @@ struct obs_encoder {
pthread_mutex_t outputs_mutex;
DARRAY(obs_output_t *) outputs;
bool destroy_on_stop;
/* stores the video/audio media output pointer. video_t *or audio_t **/
void *media;

View File

@@ -290,6 +290,7 @@ void obs_output_destroy(obs_output_t *output)
if (output->video_encoders[i]) {
obs_encoder_remove_output(
output->video_encoders[i], output);
obs_encoder_release(output->video_encoders[i]);
}
if (output->caption_tracks[i]) {
destroy_caption_track(
@@ -301,6 +302,7 @@ void obs_output_destroy(obs_output_t *output)
if (output->audio_encoders[i]) {
obs_encoder_remove_output(
output->audio_encoders[i], output);
obs_encoder_release(output->audio_encoders[i]);
}
}
@@ -970,14 +972,18 @@ void obs_output_remove_encoder_internal(struct obs_output *output,
if (encoder->info.type == OBS_ENCODER_VIDEO) {
for (size_t i = 0; i < MAX_OUTPUT_VIDEO_ENCODERS; i++) {
obs_encoder_t *video = output->video_encoders[i];
if (video == encoder)
if (video == encoder) {
output->video_encoders[i] = NULL;
obs_encoder_release(video);
}
}
} else if (encoder->info.type == OBS_ENCODER_AUDIO) {
for (size_t i = 0; i < MAX_OUTPUT_AUDIO_ENCODERS; i++) {
obs_encoder_t *audio = output->audio_encoders[i];
if (audio == encoder)
if (audio == encoder) {
output->audio_encoders[i] = NULL;
obs_encoder_release(audio);
}
}
}
}
@@ -1041,8 +1047,10 @@ void obs_output_set_video_encoder2(obs_output_t *output, obs_encoder_t *encoder,
return;
obs_encoder_remove_output(output->video_encoders[idx], output);
obs_encoder_add_output(encoder, output);
output->video_encoders[idx] = encoder;
obs_encoder_release(output->video_encoders[idx]);
output->video_encoders[idx] = obs_encoder_get_ref(encoder);
obs_encoder_add_output(output->video_encoders[idx], output);
destroy_caption_track(&output->caption_tracks[idx]);
if (encoder != NULL) {
@@ -1104,8 +1112,10 @@ void obs_output_set_audio_encoder(obs_output_t *output, obs_encoder_t *encoder,
return;
obs_encoder_remove_output(output->audio_encoders[idx], output);
obs_encoder_add_output(encoder, output);
output->audio_encoders[idx] = encoder;
obs_encoder_release(output->audio_encoders[idx]);
output->audio_encoders[idx] = obs_encoder_get_ref(encoder);
obs_encoder_add_output(output->audio_encoders[idx], output);
}
obs_encoder_t *obs_output_get_video_encoder2(const obs_output_t *output,