diff options
author | Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | 2015-01-16 15:21:14 +0000 |
---|---|---|
committer | Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | 2015-01-16 15:55:10 +0000 |
commit | 6ab711f3f102da0fa8d4f9feabfe7f3f4e8a0d6e (patch) | |
tree | b9fd6bba0b08528e1d96c422e799b743f326cd82 /gst/playback/gstdecodebin2.c | |
parent | fbff44711afa01e1c4f2dff7a6f3f960ab36ec13 (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.c | 52 |
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); |