Просмотр исходного кода

libobs: Use weak reference for paired encoders

derrod 1 год назад
Родитель
Сommit
c422a336fc
4 измененных файлов с 42 добавлено и 15 удалено
  1. 21 6
      libobs/obs-encoder.c
  2. 1 1
      libobs/obs-internal.h
  3. 6 2
      libobs/obs-output.c
  4. 14 6
      libobs/obs-video-gpu-encode.c

+ 21 - 6
libobs/obs-encoder.c

@@ -690,12 +690,17 @@ void obs_encoder_shutdown(obs_encoder_t *encoder)
 	if (encoder->context.data) {
 		encoder->info.destroy(encoder->context.data);
 		encoder->context.data = NULL;
-		da_free(encoder->paired_encoders);
 		encoder->first_received = false;
 		encoder->offset_usec = 0;
 		encoder->start_ts = 0;
 		encoder->frame_rate_divisor_counter = 0;
 		maybe_clear_encoder_core_video_mix(encoder);
+
+		for (size_t i = 0; i < encoder->paired_encoders.num; i++) {
+			obs_weak_encoder_release(
+				encoder->paired_encoders.array[i]);
+		}
+		da_free(encoder->paired_encoders);
 	}
 	obs_encoder_set_last_error(encoder, NULL);
 	pthread_mutex_unlock(&encoder->init_mutex);
@@ -1427,7 +1432,6 @@ static void receive_video(void *param, struct video_data *frame)
 	profile_start(receive_video_name);
 
 	struct obs_encoder *encoder = param;
-	struct obs_encoder **paired = encoder->paired_encoders.array;
 	struct encoder_frame enc_frame;
 
 	if (encoder->encoder_group && !encoder->start_ts) {
@@ -1442,10 +1446,18 @@ static void receive_video(void *param, struct video_data *frame)
 
 	if (!encoder->first_received && encoder->paired_encoders.num) {
 		for (size_t i = 0; i < encoder->paired_encoders.num; i++) {
-			if (!paired[i]->first_received ||
-			    paired[i]->first_raw_ts > frame->timestamp) {
+			obs_encoder_t *paired = obs_weak_encoder_get_encoder(
+				encoder->paired_encoders.array[i]);
+			if (!paired)
+				continue;
+
+			if (!paired->first_received ||
+			    paired->first_raw_ts > frame->timestamp) {
+				obs_encoder_release(paired);
 				goto wait_for_audio;
 			}
+
+			obs_encoder_release(paired);
 		}
 	}
 
@@ -1535,8 +1547,10 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
 
 	struct obs_encoder *paired_encoder = NULL;
 	/* Audio encoders can only be paired to one video encoder */
-	if (encoder->paired_encoders.num)
-		paired_encoder = encoder->paired_encoders.array[0];
+	if (encoder->paired_encoders.num) {
+		paired_encoder = obs_weak_encoder_get_encoder(
+			encoder->paired_encoders.array[0]);
+	}
 
 	if (!encoder->start_ts && paired_encoder) {
 		uint64_t end_ts = data->timestamp;
@@ -1577,6 +1591,7 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
 
 fail:
 	push_back_audio(encoder, data, size, offset_size);
+	obs_encoder_release(paired_encoder);
 
 	profile_end(buffer_audio_name);
 	return success;

+ 1 - 1
libobs/obs-internal.h

@@ -1315,7 +1315,7 @@ struct obs_encoder {
 	 * up at the specific timestamp.  if this is the audio encoder,
 	 * it waits until it's ready to sync up with video */
 	bool first_received;
-	DARRAY(struct obs_encoder *) paired_encoders;
+	DARRAY(struct obs_weak_encoder *) paired_encoders;
 	int64_t offset_usec;
 	uint64_t first_raw_ts;
 	uint64_t start_ts;

+ 6 - 2
libobs/obs-output.c

@@ -2656,8 +2656,12 @@ static inline void pair_encoders(obs_output_t *output)
 
 		pthread_mutex_lock(&audio->init_mutex);
 		if (!audio->active && !audio->paired_encoders.num) {
-			da_push_back(video->paired_encoders, &audio);
-			da_push_back(audio->paired_encoders, &video);
+			obs_weak_encoder_t *weak_audio =
+				obs_encoder_get_weak_encoder(audio);
+			obs_weak_encoder_t *weak_video =
+				obs_encoder_get_weak_encoder(video);
+			da_push_back(video->paired_encoders, &weak_audio);
+			da_push_back(audio->paired_encoders, &weak_video);
 		}
 		pthread_mutex_unlock(&audio->init_mutex);
 	}

+ 14 - 6
libobs/obs-video-gpu-encode.c

@@ -82,7 +82,7 @@ static void *gpu_encode_thread(void *data)
 			uint32_t skip = 0;
 
 			obs_encoder_t *encoder = encoders.array[i];
-			struct obs_encoder **paired =
+			obs_weak_encoder_t **paired =
 				encoder->paired_encoders.array;
 			size_t num_paired = encoder->paired_encoders.num;
 
@@ -105,13 +105,21 @@ static void *gpu_encode_thread(void *data)
 			if (!encoder->first_received && num_paired) {
 				bool wait_for_audio = false;
 
-				for (size_t idx = 0; idx < num_paired; idx++) {
-					if (!paired[idx]->first_received ||
-					    paired[idx]->first_raw_ts >
-						    timestamp) {
+				for (size_t idx = 0;
+				     !wait_for_audio && idx < num_paired;
+				     idx++) {
+					obs_encoder_t *enc =
+						obs_weak_encoder_get_encoder(
+							paired[idx]);
+					if (!enc)
+						continue;
+
+					if (!enc->first_received ||
+					    enc->first_raw_ts > timestamp) {
 						wait_for_audio = true;
-						break;
 					}
+
+					obs_encoder_release(enc);
 				}
 
 				if (wait_for_audio)