Skip to content

Commit dc0ff2a

Browse files
committed
video player: disable hw decoding for gstreamer < 1.22.8
There's an issue in the gstreamer video4linux2 plugin where seeking will lead to buffer management issues, causing streaming to stop, or even memory leaks. See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4465
1 parent 58663ba commit dc0ff2a

File tree

1 file changed

+34
-5
lines changed
  • src/plugins/gstreamer_video_player

1 file changed

+34
-5
lines changed

src/plugins/gstreamer_video_player/player.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -660,10 +660,23 @@ void on_source_setup(GstElement *playbin, GstElement *source, gpointer userdata)
660660
}
661661
}
662662

663+
/**
664+
* See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-base/gst/playback/gstplay-enum.h
665+
*/
663666
typedef enum {
664-
GST_PLAY_FLAG_VIDEO = (1 << 0),
665-
GST_PLAY_FLAG_AUDIO = (1 << 1),
666-
GST_PLAY_FLAG_TEXT = (1 << 2)
667+
GST_PLAY_FLAG_VIDEO = (1 << 0),
668+
GST_PLAY_FLAG_AUDIO = (1 << 1),
669+
GST_PLAY_FLAG_TEXT = (1 << 2),
670+
GST_PLAY_FLAG_VIS = (1 << 3),
671+
GST_PLAY_FLAG_SOFT_VOLUME = (1 << 4),
672+
GST_PLAY_FLAG_NATIVE_AUDIO = (1 << 5),
673+
GST_PLAY_FLAG_NATIVE_VIDEO = (1 << 6),
674+
GST_PLAY_FLAG_DOWNLOAD = (1 << 7),
675+
GST_PLAY_FLAG_BUFFERING = (1 << 8),
676+
GST_PLAY_FLAG_DEINTERLACE = (1 << 9),
677+
GST_PLAY_FLAG_SOFT_COLORBALANCE = (1 << 10),
678+
GST_PLAY_FLAG_FORCE_FILTERS = (1 << 11),
679+
GST_PLAY_FLAG_FORCE_SW_DECODERS = (1 << 12),
667680
} GstPlayFlags;
668681

669682
static void on_element_setup(GstElement *playbin, GstElement *element, gpointer userdata) {
@@ -772,8 +785,13 @@ static struct gstplayer *gstplayer_new_v2(struct flutterpi *flutterpi, const cha
772785
value_notifier_init(&p->buffering_state_notifier, NULL, free);
773786
change_notifier_init(&p->error_notifier);
774787

775-
/// TODO: Use playbin or playbin3?
788+
// playbin3 doesn't let use disable hardware decoders,
789+
// which we need to do for gstreamer < 1.22.8.
790+
#if THIS_GSTREAMER_VER < GSTREAMER_VER(1, 22, 8)
791+
p->playbin = gst_element_factory_make("playbin", "playbin");
792+
#else
776793
p->playbin = gst_element_factory_make("playbin3", "playbin");
794+
#endif
777795
if (p->playbin == NULL) {
778796
LOG_PLAYER_ERROR(p, "Couldn't create playbin instance.\n");
779797
goto fail_free_p;
@@ -803,6 +821,17 @@ static struct gstplayer *gstplayer_new_v2(struct flutterpi *flutterpi, const cha
803821
flags &= ~GST_PLAY_FLAG_TEXT;
804822
}
805823

824+
// Gstreamer older than 1.22.8 has a buffer management issue when seeking.
825+
// https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4465
826+
//
827+
// This is a bit more coarse than necessary; we technically only
828+
// need to disable the v4l2 decoders.
829+
#if THIS_GSTREAMER_VER < GSTREAMER_VER(1, 22, 8)
830+
flags |= GST_PLAY_FLAG_FORCE_SW_DECODERS;
831+
#else
832+
flags &= ~GST_PLAY_FLAG_FORCE_SW_DECODERS;
833+
#endif
834+
806835
g_object_set(p->playbin, "flags", flags, NULL);
807836

808837
if (play_video) {
@@ -901,7 +930,7 @@ struct gstplayer *gstplayer_new_from_asset(struct flutterpi *flutterpi, const ch
901930
return NULL;
902931
}
903932

904-
player = gstplayer_new_v2(flutterpi, uri, userdata, true, true, false, NULL);
933+
player = gstplayer_new_v2(flutterpi, uri, userdata, /* play_video */ true, /* play_audio */ false, /* play_text */ false, NULL);
905934

906935
free(uri);
907936

0 commit comments

Comments
 (0)