mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
playbin: Implement context caching for sinks that are not in playsink yet
This commit is contained in:
parent
e21d3d214a
commit
78b0e16773
1 changed files with 83 additions and 0 deletions
|
@ -470,6 +470,8 @@ struct _GstPlayBin
|
||||||
} duration[5]; /* cached durations */
|
} duration[5]; /* cached durations */
|
||||||
|
|
||||||
guint64 ring_buffer_max_size; /* 0 means disabled */
|
guint64 ring_buffer_max_size; /* 0 means disabled */
|
||||||
|
|
||||||
|
GList *contexts;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPlayBinClass
|
struct _GstPlayBinClass
|
||||||
|
@ -1530,6 +1532,8 @@ gst_play_bin_finalize (GObject * object)
|
||||||
if (playbin->velements)
|
if (playbin->velements)
|
||||||
g_sequence_free (playbin->velements);
|
g_sequence_free (playbin->velements);
|
||||||
|
|
||||||
|
g_list_free_full (playbin->contexts, (GDestroyNotify) gst_context_unref);
|
||||||
|
|
||||||
g_rec_mutex_clear (&playbin->lock);
|
g_rec_mutex_clear (&playbin->lock);
|
||||||
g_mutex_clear (&playbin->dyn_lock);
|
g_mutex_clear (&playbin->dyn_lock);
|
||||||
g_mutex_clear (&playbin->elements_lock);
|
g_mutex_clear (&playbin->elements_lock);
|
||||||
|
@ -4061,6 +4065,34 @@ gst_play_bin_set_context (GstElement * element, GstContext * context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass sink messages to the application, e.g. NEED_CONTEXT messages */
|
/* Pass sink messages to the application, e.g. NEED_CONTEXT messages */
|
||||||
|
static void
|
||||||
|
gst_play_bin_update_context (GstPlayBin * playbin, GstContext * context)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
const gchar *context_type;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (playbin);
|
||||||
|
context_type = gst_context_get_context_type (context);
|
||||||
|
for (l = playbin->contexts; l; l = l->next) {
|
||||||
|
GstContext *tmp = l->data;
|
||||||
|
const gchar *tmp_type = gst_context_get_context_type (tmp);
|
||||||
|
|
||||||
|
/* Always store newest context but never replace
|
||||||
|
* a persistent one by a non-persistent one */
|
||||||
|
if (strcmp (context_type, tmp_type) == 0 &&
|
||||||
|
(gst_context_is_persistent (context) ||
|
||||||
|
!gst_context_is_persistent (tmp))) {
|
||||||
|
gst_context_replace ((GstContext **) & l->data, context);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Not found? Add */
|
||||||
|
if (l != NULL)
|
||||||
|
playbin->contexts =
|
||||||
|
g_list_prepend (playbin->contexts, gst_context_ref (context));
|
||||||
|
GST_OBJECT_UNLOCK (playbin);
|
||||||
|
}
|
||||||
|
|
||||||
static GstBusSyncReply
|
static GstBusSyncReply
|
||||||
activate_sink_bus_handler (GstBus * bus, GstMessage * msg, GstPlayBin * playbin)
|
activate_sink_bus_handler (GstBus * bus, GstMessage * msg, GstPlayBin * playbin)
|
||||||
{
|
{
|
||||||
|
@ -4081,6 +4113,37 @@ activate_sink_bus_handler (GstBus * bus, GstMessage * msg, GstPlayBin * playbin)
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
||||||
else
|
else
|
||||||
gst_message_unref (msg);
|
gst_message_unref (msg);
|
||||||
|
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_NEED_CONTEXT) {
|
||||||
|
const gchar *context_type;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
gst_message_parse_context_type (msg, &context_type);
|
||||||
|
GST_OBJECT_LOCK (playbin);
|
||||||
|
for (l = playbin->contexts; l; l = l->next) {
|
||||||
|
GstContext *tmp = l->data;
|
||||||
|
const gchar *tmp_type = gst_context_get_context_type (tmp);
|
||||||
|
|
||||||
|
if (strcmp (context_type, tmp_type) == 0) {
|
||||||
|
gst_element_set_context (GST_ELEMENT (GST_MESSAGE_SRC (msg)), l->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (playbin);
|
||||||
|
|
||||||
|
/* Forward if we couldn't answer the message */
|
||||||
|
if (l == NULL) {
|
||||||
|
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
||||||
|
} else {
|
||||||
|
gst_message_unref (msg);
|
||||||
|
}
|
||||||
|
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_HAVE_CONTEXT) {
|
||||||
|
GstContext *context;
|
||||||
|
|
||||||
|
gst_message_parse_have_context (msg, &context);
|
||||||
|
gst_play_bin_update_context (playbin, context);
|
||||||
|
gst_context_unref (context);
|
||||||
|
|
||||||
|
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
||||||
} else {
|
} else {
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
|
||||||
}
|
}
|
||||||
|
@ -5379,6 +5442,7 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
/* also do missed state change down to READY */
|
/* also do missed state change down to READY */
|
||||||
if (do_save)
|
if (do_save)
|
||||||
|
@ -5425,6 +5489,25 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
/* make sure the groups don't perform a state change anymore until we
|
/* make sure the groups don't perform a state change anymore until we
|
||||||
* enable them again */
|
* enable them again */
|
||||||
groups_set_locked_state (playbin, TRUE);
|
groups_set_locked_state (playbin, TRUE);
|
||||||
|
|
||||||
|
/* Remove all non-persistent contexts */
|
||||||
|
GST_OBJECT_LOCK (playbin);
|
||||||
|
for (l = playbin->contexts; l;) {
|
||||||
|
GstContext *context = l->data;
|
||||||
|
|
||||||
|
if (!gst_context_is_persistent (context)) {
|
||||||
|
GList *next;
|
||||||
|
|
||||||
|
gst_context_unref (context);
|
||||||
|
|
||||||
|
next = l->next;
|
||||||
|
playbin->contexts = g_list_delete_link (playbin->contexts, l);
|
||||||
|
l = next;
|
||||||
|
} else {
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (playbin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue