Răsfoiți Sursa

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.
derrod 1 an în urmă
părinte
comite
2c57f4564c
3 a modificat fișierele cu 17 adăugiri și 34 ștergeri
  1. 1 26
      libobs/obs-encoder.c
  2. 0 2
      libobs/obs-internal.h
  3. 16 6
      libobs/obs-output.c

+ 1 - 26
libobs/obs-encoder.c

@@ -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

+ 0 - 2
libobs/obs-internal.h

@@ -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;
 

+ 16 - 6
libobs/obs-output.c

@@ -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,