summaryrefslogtreecommitdiff
path: root/gst/playback/gstdecodebin2.c
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2015-01-16 15:21:14 +0000
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2015-01-16 15:55:10 +0000
commit6ab711f3f102da0fa8d4f9feabfe7f3f4e8a0d6e (patch)
treeb9fd6bba0b08528e1d96c422e799b743f326cd82 /gst/playback/gstdecodebin2.c
parentfbff44711afa01e1c4f2dff7a6f3f960ab36ec13 (diff)
decodebin: free old groups when switching groups
Old groups are freed with one switch's delay when switching groups. They're freed in a scratch thread to avoid delaying the switch.
Diffstat (limited to 'gst/playback/gstdecodebin2.c')
-rw-r--r--gst/playback/gstdecodebin2.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c
index 813fcc719..f0f1ab807 100644
--- a/gst/playback/gstdecodebin2.c
+++ b/gst/playback/gstdecodebin2.c
@@ -3417,6 +3417,57 @@ gst_decode_group_hide (GstDecodeGroup * group)
gst_decode_group_free_internal (group, TRUE);
}
+/* gst_decode_chain_free_hidden_groups:
+ *
+ * Frees any decode groups that were hidden previously.
+ * This allows keeping memory use from ballooning when
+ * switching chains repeatedly.
+ *
+ * A new throwaway thread will be created to free the
+ * groups, so any delay does not block the setup of a
+ * new group.
+ *
+ * Not MT-safe, call with parent's chain lock!
+ */
+static void
+gst_decode_chain_free_hidden_groups (GList * old_groups)
+{
+ GList *l;
+
+ for (l = old_groups; l; l = l->next) {
+ GstDecodeGroup *group = l->data;
+
+ gst_decode_group_free (group);
+ }
+ g_list_free (old_groups);
+}
+
+static void
+gst_decode_chain_start_free_hidden_groups_thread (GstDecodeChain * chain)
+{
+ GThread *thread;
+ GError *error = NULL;
+ GList *old_groups;
+
+ old_groups = chain->old_groups;
+ if (!old_groups)
+ return;
+
+ chain->old_groups = NULL;
+ thread = g_thread_try_new ("free-hidden-groups",
+ (GThreadFunc) gst_decode_chain_free_hidden_groups, old_groups, &error);
+ if (!thread || error) {
+ GST_ERROR ("Failed to start free-hidden-groups thread: %s",
+ error ? error->message : "unknown reason");
+ g_clear_error (&error);
+ chain->old_groups = old_groups;
+ return;
+ }
+ GST_DEBUG_OBJECT (chain->dbin, "Started free-hidden-groups thread");
+ /* We do not need to wait for it or get any results from it */
+ g_thread_unref (thread);
+}
+
/* configure queue sizes, this depends on the buffering method and if we are
* playing or prerolling. */
static void
@@ -3760,6 +3811,7 @@ drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * drainpad,
if (chain->next_groups) {
/* Switch to next group */
GST_DEBUG_OBJECT (dbin, "Hiding current group %p", chain->active_group);
+ gst_decode_chain_start_free_hidden_groups_thread (chain);
gst_decode_group_hide (chain->active_group);
chain->old_groups =
g_list_prepend (chain->old_groups, chain->active_group);