Browse Source

obs-ffmpeg: Add network buffering property

(Note: This commit also modifies deps/media-playback)

Allows buffering network-based media sources where supported.  Default
is two megabytes of buffering.
jp9000 8 năm trước cách đây
mục cha
commit
892a6548e7

+ 13 - 2
deps/media-playback/media-playback/media.c

@@ -497,7 +497,14 @@ static bool init_avformat(mp_media_t *m)
 					"'%s'", m->path);
 	}
 
-	int ret = avformat_open_input(&m->fmt, m->path, format, NULL);
+	AVDictionary *opts = NULL;
+	if (m->buffering && m->is_network)
+		av_dict_set_int(&opts, "buffer_size", m->buffering, 0);
+
+	int ret = avformat_open_input(&m->fmt, m->path, format,
+			opts ? &opts : NULL);
+	av_dict_free(&opts);
+
 	if (ret < 0) {
 		blog(LOG_WARNING, "MP: Failed to open media: '%s'", m->path);
 		return false;
@@ -531,7 +538,9 @@ static void *mp_media_thread(void *opaque)
 		return NULL;
 	}
 
-	mp_media_reset(m);
+	if (!mp_media_reset(m)) {
+		return NULL;
+	}
 
 	for (;;) {
 		bool reset, kill, is_active;
@@ -613,6 +622,7 @@ static inline bool mp_media_init_internal(mp_media_t *m,
 bool mp_media_init(mp_media_t *media,
 		const char *path,
 		const char *format,
+		int buffering,
 		void *opaque,
 		mp_video_cb v_cb,
 		mp_audio_cb a_cb,
@@ -629,6 +639,7 @@ bool mp_media_init(mp_media_t *media,
 	media->stop_cb = stop_cb;
 	media->v_preload_cb = v_preload_cb;
 	media->force_range = force_range;
+	media->buffering = buffering;
 
 	if (path && *path)
 		media->is_network = !!strstr(path, "://");

+ 2 - 0
deps/media-playback/media-playback/media.h

@@ -53,6 +53,7 @@ struct mp_media {
 
 	char *path;
 	char *format_name;
+	int buffering;
 
 	enum AVPixelFormat scale_format;
 	struct SwsContext *swscale;
@@ -96,6 +97,7 @@ typedef struct mp_media mp_media_t;
 extern bool mp_media_init(mp_media_t *media,
 		const char *path,
 		const char *format,
+		int buffering,
 		void *opaque,
 		mp_video_cb v_cb,
 		mp_audio_cb a_cb,

+ 1 - 0
plugins/obs-ffmpeg/data/locale/en-US.ini

@@ -23,6 +23,7 @@ LocalFile="Local File"
 Looping="Loop"
 Input="Input"
 InputFormat="Input Format"
+BufferingMB="Network Buffering (MB)"
 HardwareDecode="Use hardware decoding when available"
 ClearOnMediaEnd="Hide source when playback ends"
 Advanced="Advanced"

+ 10 - 0
plugins/obs-ffmpeg/obs-ffmpeg-source.c

@@ -51,6 +51,7 @@ struct ffmpeg_source {
 
 	char *input;
 	char *input_format;
+	int buffering_mb;
 	bool is_looping;
 	bool is_local_file;
 	bool is_hw_decoding;
@@ -70,9 +71,11 @@ static bool is_local_file_modified(obs_properties_t *props,
 			"input_format");
 	obs_property_t *local_file = obs_properties_get(props, "local_file");
 	obs_property_t *looping = obs_properties_get(props, "looping");
+	obs_property_t *buffering = obs_properties_get(props, "buffering_mb");
 	obs_property_t *close = obs_properties_get(props, "close_when_inactive");
 	obs_property_set_visible(input, !enabled);
 	obs_property_set_visible(input_format, !enabled);
+	obs_property_set_visible(buffering, !enabled);
 	obs_property_set_visible(close, enabled);
 	obs_property_set_visible(local_file, enabled);
 	obs_property_set_visible(looping, enabled);
@@ -89,6 +92,7 @@ static void ffmpeg_source_defaults(obs_data_t *settings)
 #if defined(_WIN32)
 	obs_data_set_default_bool(settings, "hw_decode", true);
 #endif
+	obs_data_set_default_int(settings, "buffering_mb", 2);
 }
 
 static const char *media_filter =
@@ -153,6 +157,10 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data)
 	obs_properties_add_text(props, "input_format",
 			obs_module_text("InputFormat"), OBS_TEXT_DEFAULT);
 
+	obs_properties_add_int(props, "buffering_mb",
+			obs_module_text("BufferingMB"),
+			0, 50, 1);
+
 #ifndef __APPLE__
 	obs_properties_add_bool(props, "hw_decode",
 			obs_module_text("HardwareDecode"));
@@ -234,6 +242,7 @@ static void ffmpeg_source_open(struct ffmpeg_source *s)
 	if (s->input && *s->input)
 		s->media_valid = mp_media_init(&s->media,
 				s->input, s->input_format,
+				s->buffering_mb * 1024 * 1024,
 				s, get_frame, get_audio, media_stopped,
 				preload_frame, s->is_hw_decoding, s->range);
 }
@@ -303,6 +312,7 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings)
 			"restart_on_activate");
 	s->range = (enum video_range_type)obs_data_get_int(settings,
 			"color_range");
+	s->buffering_mb = (int)obs_data_get_int(settings, "buffering_mb");
 	s->is_local_file = is_local_file;
 
 	if (s->media_valid) {