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

obs-ffmpeg: Fix srt/rist not working

This fixes a bug where the new circular buffer code is hit by protocols
such as rist or srt although the buffer was meant for files.

Signed-off-by: pkv <[email protected]>
pkv 3 лет назад
Родитель
Сommit
b9237aed29
1 измененных файлов с 57 добавлено и 44 удалено
  1. 57 44
      plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c

+ 57 - 44
plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c

@@ -871,6 +871,21 @@ static int ffmpeg_mux_write_av_buffer(void *opaque, uint8_t *buf, int buf_size)
 	return buf_size;
 }
 
+#define SRT_PROTO "srt"
+#define UDP_PROTO "udp"
+#define TCP_PROTO "tcp"
+#define HTTP_PROTO "http"
+#define RIST_PROTO "rist"
+
+static bool ffmpeg_mux_is_network(struct ffmpeg_mux *ffm)
+{
+	return !strncmp(ffm->params.file, SRT_PROTO, sizeof(SRT_PROTO) - 1) ||
+	       !strncmp(ffm->params.file, UDP_PROTO, sizeof(UDP_PROTO) - 1) ||
+	       !strncmp(ffm->params.file, TCP_PROTO, sizeof(TCP_PROTO) - 1) ||
+	       !strncmp(ffm->params.file, HTTP_PROTO, sizeof(HTTP_PROTO) - 1) ||
+	       !strncmp(ffm->params.file, RIST_PROTO, sizeof(RIST_PROTO) - 1);
+}
+
 static inline int open_output_file(struct ffmpeg_mux *ffm)
 {
 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59, 0, 100)
@@ -881,42 +896,55 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
 	int ret;
 
 	if ((format->flags & AVFMT_NOFILE) == 0) {
-		// If not outputting to a network, write to a circlebuf
-		// instead of relying on ffmpeg disk output. This hopefully
-		// works around too small buffers somewhere causing output
-		// stalls when recording.
-
-		// We're in charge of managing the actual file now
-		ffm->io.output_file = os_fopen(ffm->params.file, "wb");
-		if (!ffm->io.output_file) {
-			fprintf(stderr, "Couldn't open '%s', %s\n",
-				ffm->params.printable_file.array,
-				strerror(errno));
-			return FFM_ERROR;
-		}
+		if (!ffmpeg_mux_is_network(ffm)) {
+			// If not outputting to a network, write to a circlebuf
+			// instead of relying on ffmpeg disk output. This hopefully
+			// works around too small buffers somewhere causing output
+			// stalls when recording.
+
+			// We're in charge of managing the actual file now
+			ffm->io.output_file = os_fopen(ffm->params.file, "wb");
+			if (!ffm->io.output_file) {
+				fprintf(stderr, "Couldn't open '%s', %s\n",
+					ffm->params.printable_file.array,
+					strerror(errno));
+				return FFM_ERROR;
+			}
 
-		// Start at 1MB, this can grow up to 256 MB depending
-		// how fast data is going in and out (limited in
-		// ffmpeg_mux_write_av_buffer)
-		circlebuf_reserve(&ffm->io.data, 1048576);
+			// Start at 1MB, this can grow up to 256 MB depending
+			// how fast data is going in and out (limited in
+			// ffmpeg_mux_write_av_buffer)
+			circlebuf_reserve(&ffm->io.data, 1048576);
 
-		pthread_mutex_init(&ffm->io.data_mutex, NULL);
+			pthread_mutex_init(&ffm->io.data_mutex, NULL);
 
-		os_event_init(&ffm->io.buffer_space_available_event,
-			      OS_EVENT_TYPE_AUTO);
-		os_event_init(&ffm->io.new_data_available_event,
-			      OS_EVENT_TYPE_AUTO);
+			os_event_init(&ffm->io.buffer_space_available_event,
+				      OS_EVENT_TYPE_AUTO);
+			os_event_init(&ffm->io.new_data_available_event,
+				      OS_EVENT_TYPE_AUTO);
 
-		pthread_create(&ffm->io.io_thread, NULL, ffmpeg_mux_io_thread,
-			       ffm);
+			pthread_create(&ffm->io.io_thread, NULL,
+				       ffmpeg_mux_io_thread, ffm);
 
-		unsigned char *avio_ctx_buffer = av_malloc(AVIO_BUFFER_SIZE);
+			unsigned char *avio_ctx_buffer =
+				av_malloc(AVIO_BUFFER_SIZE);
 
-		ffm->output->pb = avio_alloc_context(
-			avio_ctx_buffer, AVIO_BUFFER_SIZE, 1, ffm, NULL,
-			ffmpeg_mux_write_av_buffer, ffmpeg_mux_seek_av_buffer);
+			ffm->output->pb = avio_alloc_context(
+				avio_ctx_buffer, AVIO_BUFFER_SIZE, 1, ffm, NULL,
+				ffmpeg_mux_write_av_buffer,
+				ffmpeg_mux_seek_av_buffer);
 
-		ffm->io.active = true;
+			ffm->io.active = true;
+		} else {
+			ret = avio_open(&ffm->output->pb, ffm->params.file,
+					AVIO_FLAG_WRITE);
+			if (ret < 0) {
+				fprintf(stderr, "Couldn't open '%s', %s\n",
+					ffm->params.printable_file.array,
+					av_err2str(ret));
+				return FFM_ERROR;
+			}
+		}
 	}
 
 	AVDictionary *dict = NULL;
@@ -954,21 +982,6 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
 	return FFM_SUCCESS;
 }
 
-#define SRT_PROTO "srt"
-#define UDP_PROTO "udp"
-#define TCP_PROTO "tcp"
-#define HTTP_PROTO "http"
-#define RIST_PROTO "rist"
-
-static bool ffmpeg_mux_is_network(struct ffmpeg_mux *ffm)
-{
-	return !strncmp(ffm->params.file, SRT_PROTO, sizeof(SRT_PROTO) - 1) ||
-	       !strncmp(ffm->params.file, UDP_PROTO, sizeof(UDP_PROTO) - 1) ||
-	       !strncmp(ffm->params.file, TCP_PROTO, sizeof(TCP_PROTO) - 1) ||
-	       !strncmp(ffm->params.file, HTTP_PROTO, sizeof(HTTP_PROTO) - 1) ||
-	       !strncmp(ffm->params.file, RIST_PROTO, sizeof(RIST_PROTO) - 1);
-}
-
 static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
 {
 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59, 0, 100)