mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
gst/playback/gstdecodebin.c: Implement delayed caps linking needed for element with a lot of different caps on the sr...
Original commit message from CVS: * gst/playback/gstdecodebin.c: (dynamic_create), (dynamic_free), (close_pad_link), (dynamic_remove), (no_more_pads), (new_caps), (find_dynamic), (unlinked), (close_link): Implement delayed caps linking needed for element with a lot of different caps on the src pads that get fixed at runtime. Improve management of dynamic elements. * gst/playback/gstplaybasebin.c: (gst_play_base_bin_init), (group_destroy), (group_commit), (check_queue), (queue_overrun), (gen_preroll_element), (remove_groups), (unknown_type), (add_element_stream), (no_more_pads_full), (no_more_pads), (sub_no_more_pads), (source_no_more_pads), (preroll_unlinked), (new_decoded_pad), (setup_subtitle), (array_has_value), (gen_source_element), (source_new_pad), (has_all_raw_caps), (analyse_source), (remove_decoders), (make_decoder), (remove_source), (setup_source), (finish_source), (prepare_output), (gst_play_base_bin_change_state): * gst/playback/gstplaybasebin.h: Use more _CAST instead of full type checking casts. Small cleanups, plug some leaks. Handle dynamic sources. Add some helper functions to create lists of strings used for blacklisting and other stuff. Refactor some code dealing with analysing the source. Re-enable sources without pads (like cd:// or other selfcontained elements).
This commit is contained in:
parent
9945d7a468
commit
5ed137a270
4 changed files with 616 additions and 264 deletions
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
2006-09-28 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/playback/gstdecodebin.c: (dynamic_create), (dynamic_free),
|
||||
(close_pad_link), (dynamic_remove), (no_more_pads), (new_caps),
|
||||
(find_dynamic), (unlinked), (close_link):
|
||||
Implement delayed caps linking needed for element with a lot of
|
||||
different caps on the src pads that get fixed at runtime.
|
||||
Improve management of dynamic elements.
|
||||
|
||||
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_init),
|
||||
(group_destroy), (group_commit), (check_queue), (queue_overrun),
|
||||
(gen_preroll_element), (remove_groups), (unknown_type),
|
||||
(add_element_stream), (no_more_pads_full), (no_more_pads),
|
||||
(sub_no_more_pads), (source_no_more_pads), (preroll_unlinked),
|
||||
(new_decoded_pad), (setup_subtitle), (array_has_value),
|
||||
(gen_source_element), (source_new_pad), (has_all_raw_caps),
|
||||
(analyse_source), (remove_decoders), (make_decoder),
|
||||
(remove_source), (setup_source), (finish_source), (prepare_output),
|
||||
(gst_play_base_bin_change_state):
|
||||
* gst/playback/gstplaybasebin.h:
|
||||
Use more _CAST instead of full type checking casts.
|
||||
Small cleanups, plug some leaks.
|
||||
Handle dynamic sources.
|
||||
Add some helper functions to create lists of strings used for
|
||||
blacklisting and other stuff.
|
||||
Refactor some code dealing with analysing the source.
|
||||
Re-enable sources without pads (like cd:// or other selfcontained
|
||||
elements).
|
||||
|
||||
2006-09-28 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||
|
|
|
@ -111,11 +111,14 @@ typedef struct
|
|||
* at runtime */
|
||||
typedef struct
|
||||
{
|
||||
gint np_sig_id; /* signal id of new_pad */
|
||||
gint unlink_sig_id; /* signal id of unlinked */
|
||||
gint nmp_sig_id; /* signal id of no_more_pads */
|
||||
GstElement *element; /* the element sending the signal */
|
||||
GstDecodeBin *decode_bin; /* pointer to ourself */
|
||||
|
||||
GstElement *element; /* the element sending the signal */
|
||||
gint np_sig_id; /* signal id of new_pad */
|
||||
gint nmp_sig_id; /* signal id of no_more_pads */
|
||||
|
||||
GstPad *pad; /* the pad sending the signal */
|
||||
gint caps_sig_id; /* signal id of caps */
|
||||
}
|
||||
GstDynamic;
|
||||
|
||||
|
@ -130,6 +133,7 @@ static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
|||
static void add_fakesink (GstDecodeBin * decode_bin);
|
||||
static void remove_fakesink (GstDecodeBin * decode_bin);
|
||||
|
||||
static void dynamic_free (GstDynamic * dyn);
|
||||
static void free_dynamics (GstDecodeBin * decode_bin);
|
||||
static void type_found (GstElement * typefind, guint probability,
|
||||
GstCaps * caps, GstDecodeBin * decode_bin);
|
||||
|
@ -142,6 +146,7 @@ static void unlinked (GstPad * pad, GstPad * peerpad,
|
|||
GstDecodeBin * decode_bin);
|
||||
static void new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic);
|
||||
static void no_more_pads (GstElement * element, GstDynamic * dynamic);
|
||||
static void new_caps (GstPad * pad, GParamSpec * unused, GstDynamic * dynamic);
|
||||
|
||||
static void queue_filled_cb (GstElement * queue, GstDecodeBin * decode_bin);
|
||||
static void queue_underrun_cb (GstElement * queue, GstDecodeBin * decode_bin);
|
||||
|
@ -238,8 +243,6 @@ gst_decode_bin_is_dynamic (GstDecodeBin * decode_bin)
|
|||
return decode_bin->dynamics != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* the filter function for selecting the elements we can use in
|
||||
* autoplugging */
|
||||
static gboolean
|
||||
|
@ -351,8 +354,6 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
|
|||
decode_bin->probes = NULL;
|
||||
}
|
||||
|
||||
static void dynamic_free (GstDynamic * dyn);
|
||||
|
||||
static void
|
||||
gst_decode_bin_dispose (GObject * object)
|
||||
{
|
||||
|
@ -383,23 +384,33 @@ gst_decode_bin_finalize (GObject * object)
|
|||
}
|
||||
|
||||
static GstDynamic *
|
||||
dynamic_create (GstElement * element, GstDecodeBin * decode_bin)
|
||||
dynamic_create (GstElement * element, GstPad * pad, GstDecodeBin * decode_bin)
|
||||
{
|
||||
GstDynamic *dyn;
|
||||
|
||||
GST_DEBUG_OBJECT (element, "dynamic create");
|
||||
|
||||
/* take refs */
|
||||
gst_object_ref (element);
|
||||
gst_object_ref (decode_bin);
|
||||
|
||||
dyn = g_new0 (GstDynamic, 1);
|
||||
dyn->element = element;
|
||||
dyn->decode_bin = decode_bin;
|
||||
dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "pad-added",
|
||||
G_CALLBACK (new_pad), dyn);
|
||||
dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads",
|
||||
G_CALLBACK (no_more_pads), dyn);
|
||||
dyn->pad = pad;
|
||||
dyn->decode_bin = gst_object_ref (decode_bin);
|
||||
if (element) {
|
||||
gst_object_ref (element);
|
||||
dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "pad-added",
|
||||
G_CALLBACK (new_pad), dyn);
|
||||
dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads",
|
||||
G_CALLBACK (no_more_pads), dyn);
|
||||
}
|
||||
if (pad) {
|
||||
gst_object_ref (pad);
|
||||
dyn->caps_sig_id = g_signal_connect (G_OBJECT (pad), "notify::caps",
|
||||
G_CALLBACK (new_caps), dyn);
|
||||
}
|
||||
|
||||
/* and add this element to the dynamic elements */
|
||||
decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
|
||||
|
||||
return dyn;
|
||||
}
|
||||
|
@ -410,13 +421,23 @@ dynamic_free (GstDynamic * dyn)
|
|||
GST_DEBUG_OBJECT (dyn->decode_bin, "dynamic free");
|
||||
|
||||
/* disconnect signals */
|
||||
g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->np_sig_id);
|
||||
g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->nmp_sig_id);
|
||||
if (dyn->np_sig_id)
|
||||
g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->np_sig_id);
|
||||
if (dyn->nmp_sig_id)
|
||||
g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->nmp_sig_id);
|
||||
if (dyn->caps_sig_id)
|
||||
g_signal_handler_disconnect (G_OBJECT (dyn->pad), dyn->caps_sig_id);
|
||||
|
||||
gst_object_unref (dyn->element);
|
||||
gst_object_unref (dyn->decode_bin);
|
||||
if (dyn->pad)
|
||||
gst_object_unref (dyn->pad);
|
||||
dyn->pad = NULL;
|
||||
if (dyn->element)
|
||||
gst_object_unref (dyn->element);
|
||||
dyn->element = NULL;
|
||||
|
||||
gst_object_unref (dyn->decode_bin);
|
||||
dyn->decode_bin = NULL;
|
||||
|
||||
g_free (dyn);
|
||||
}
|
||||
|
||||
|
@ -732,8 +753,12 @@ many_types:
|
|||
{
|
||||
/* FIXME, actually wait */
|
||||
GST_LOG_OBJECT (pad, "many possible types, implement delayed linking!");
|
||||
g_signal_emit (G_OBJECT (decode_bin),
|
||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
|
||||
goto setup_caps_delay;
|
||||
}
|
||||
setup_caps_delay:
|
||||
{
|
||||
GST_LOG_OBJECT (pad, "many possible types, delay link");
|
||||
dynamic_create (element, pad, decode_bin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1207,20 +1232,12 @@ shutting_down2:
|
|||
}
|
||||
}
|
||||
|
||||
/* this signal is fired when an element signals the no_more_pads signal.
|
||||
* This means that the element will not generate more dynamic pads and
|
||||
* we can remove the element from the list of dynamic elements. When we
|
||||
* have no more dynamic elements in the pipeline, we can fire a no_more_pads
|
||||
* signal ourselves. */
|
||||
static void
|
||||
no_more_pads (GstElement * element, GstDynamic * dynamic)
|
||||
dynamic_remove (GstDynamic * dynamic)
|
||||
{
|
||||
GstDecodeBin *decode_bin = dynamic->decode_bin;
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
|
||||
GST_ELEMENT_NAME (element));
|
||||
|
||||
/* remove the element from the list of dynamic elements */
|
||||
/* remove the dynamic from the list of dynamics */
|
||||
decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
|
||||
dynamic_free (dynamic);
|
||||
|
||||
|
@ -1240,6 +1257,34 @@ no_more_pads (GstElement * element, GstDynamic * dynamic)
|
|||
}
|
||||
}
|
||||
|
||||
/* this signal is fired when an element signals the no_more_pads signal.
|
||||
* This means that the element will not generate more dynamic pads and
|
||||
* we can remove the element from the list of dynamic elements. When we
|
||||
* have no more dynamic elements in the pipeline, we can fire a no_more_pads
|
||||
* signal ourselves. */
|
||||
static void
|
||||
no_more_pads (GstElement * element, GstDynamic * dynamic)
|
||||
{
|
||||
GstDecodeBin *decode_bin = dynamic->decode_bin;
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
|
||||
GST_ELEMENT_NAME (element));
|
||||
|
||||
dynamic_remove (dynamic);
|
||||
}
|
||||
|
||||
static void
|
||||
new_caps (GstPad * pad, GParamSpec * unused, GstDynamic * dynamic)
|
||||
{
|
||||
g_print ("delayed link triggered\n");
|
||||
new_pad (dynamic->element, pad, dynamic);
|
||||
|
||||
/* assume it worked and remove the dynamic */
|
||||
dynamic_remove (dynamic);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_our_kid (GstElement * e, GstDecodeBin * decode_bin)
|
||||
{
|
||||
|
@ -1255,6 +1300,12 @@ is_our_kid (GstElement * e, GstDecodeBin * decode_bin)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gint
|
||||
find_dynamic (GstDynamic * dyn, GstElement * elem)
|
||||
{
|
||||
return (dyn->element == elem ? 0 : 1);
|
||||
}
|
||||
|
||||
/* This function will be called when a pad is disconnected for some reason */
|
||||
static void
|
||||
unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
|
||||
|
@ -1278,14 +1329,11 @@ unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
|
|||
remove_element_chain (decode_bin, peerpad);
|
||||
|
||||
/* if an element removes two pads, then we don't want this twice */
|
||||
/* FIXME: decode_bin->dynamics doesn't contain a list of GstElements, it
|
||||
* has GstDynamic structures */
|
||||
if (g_list_find (decode_bin->dynamics, element) != NULL)
|
||||
if (g_list_find_custom (decode_bin->dynamics, element,
|
||||
(GCompareFunc) find_dynamic) != NULL)
|
||||
goto exit;
|
||||
|
||||
dyn = dynamic_create (element, decode_bin);
|
||||
/* and add this element to the dynamic elements */
|
||||
decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
|
||||
dyn = dynamic_create (element, NULL, decode_bin);
|
||||
|
||||
exit:
|
||||
gst_object_unref (element);
|
||||
|
@ -1372,9 +1420,7 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
|
|||
/* ok, this element has dynamic pads, set up the signal handlers to be
|
||||
* notified of them */
|
||||
|
||||
dyn = dynamic_create (element, decode_bin);
|
||||
/* and add this element to the dynamic elements */
|
||||
decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
|
||||
dyn = dynamic_create (element, NULL, decode_bin);
|
||||
}
|
||||
|
||||
/* Check if this is an element with more than 1 pad. If this element
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -79,7 +79,7 @@ struct _GstPlayBaseBin {
|
|||
gchar *uri, *suburi;
|
||||
gboolean is_stream;
|
||||
GstElement *source;
|
||||
GstElement *decoder;
|
||||
GSList *decoders;
|
||||
GstElement *subtitle; /* additional filesrc ! subparse bin */
|
||||
gboolean subtitle_done;
|
||||
gboolean need_rebuild;
|
||||
|
@ -93,6 +93,11 @@ struct _GstPlayBaseBin {
|
|||
GCond *group_cond;
|
||||
GstPlayBaseGroup *building_group; /* the group that we are constructing */
|
||||
GList *queued_groups; /* the constructed groups, head is the active one */
|
||||
|
||||
/* for dynamic sources */
|
||||
guint src_np_sig_id; /* new-pad signal id */
|
||||
guint src_nmp_sig_id; /* no-more-pads signal id */
|
||||
gint pending;
|
||||
};
|
||||
|
||||
struct _GstPlayBaseBinClass {
|
||||
|
|
Loading…
Reference in a new issue