mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-10 11:29:55 +00:00
gst/elements/gstfakesrc.c (gst_fakesrc_class_init): Add HAS_LOOP and HAS_GETRANGE properties, readwrite + construct.
Original commit message from CVS: 2005-02-18 Andy Wingo <wingo@pobox.com> * gst/elements/gstfakesrc.c (gst_fakesrc_class_init): Add HAS_LOOP and HAS_GETRANGE properties, readwrite + construct. (gst_fakesrc_set_pad_functions) (gst_fakesrc_set_all_pad_functions): New procs, like in fakesrc. (gst_fakesrc_set_property, gst_fakesrc_get_property): Same as fakesrc. (gst_fakesrc_get_range_unlocked): New proc, factored out of the core of _loop. (gst_fakesrc_get_range): Getrange implementation for fakesink. (gst_fakesrc_loop): Interface with get_range_unlocked. (gst_fakesrc_activate): Add support for both activation modes, with assertions. * gst/elements/gstfakesink.h: * gst/elements/gstfakesrc.h: Add has_loop and has_chain instance variables. * gst/elements/gstfakesink.c (gst_fakesink_class_init): Add HAS_LOOP and HAS_CHAIN object properties, readwrite but also set on construction. (gst_fakesink_set_pad_functions): New proc, sets the functions on one pad, setting the loop and chain functions properly. (gst_fakesink_set_all_pad_functions): New proc, does set_pad_functions on all pads. (gst_fakesink_request_new_pad): Call set_pad_functions. (gst_fakesink_set_property, gst_fakesink_get_property): When the HAS_LOOP and HAS_CHAIN properties are set, reset the functions on all pads. (gst_fakesink_activate): Assert that the appropriate functions are available for the activation mode. (gst_fakesink_loop): Don't unref the buffer, chain_unlocked does it for us.
This commit is contained in:
parent
325219ea1a
commit
69e9ca3e5f
9 changed files with 399 additions and 164 deletions
35
ChangeLog
35
ChangeLog
|
@ -1,3 +1,38 @@
|
||||||
|
2005-02-18 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst/elements/gstfakesrc.c (gst_fakesrc_class_init): Add HAS_LOOP
|
||||||
|
and HAS_GETRANGE properties, readwrite + construct.
|
||||||
|
(gst_fakesrc_set_pad_functions)
|
||||||
|
(gst_fakesrc_set_all_pad_functions): New procs, like in fakesrc.
|
||||||
|
(gst_fakesrc_set_property, gst_fakesrc_get_property): Same as
|
||||||
|
fakesrc.
|
||||||
|
(gst_fakesrc_get_range_unlocked): New proc, factored out of the
|
||||||
|
core of _loop.
|
||||||
|
(gst_fakesrc_get_range): Getrange implementation for fakesink.
|
||||||
|
(gst_fakesrc_loop): Interface with get_range_unlocked.
|
||||||
|
(gst_fakesrc_activate): Add support for both activation modes,
|
||||||
|
with assertions.
|
||||||
|
|
||||||
|
* gst/elements/gstfakesink.h:
|
||||||
|
* gst/elements/gstfakesrc.h: Add has_loop and has_chain instance
|
||||||
|
variables.
|
||||||
|
|
||||||
|
* gst/elements/gstfakesink.c (gst_fakesink_class_init): Add
|
||||||
|
HAS_LOOP and HAS_CHAIN object properties, readwrite but also set
|
||||||
|
on construction.
|
||||||
|
(gst_fakesink_set_pad_functions): New proc, sets the functions on
|
||||||
|
one pad, setting the loop and chain functions properly.
|
||||||
|
(gst_fakesink_set_all_pad_functions): New proc, does
|
||||||
|
set_pad_functions on all pads.
|
||||||
|
(gst_fakesink_request_new_pad): Call set_pad_functions.
|
||||||
|
(gst_fakesink_set_property, gst_fakesink_get_property): When the
|
||||||
|
HAS_LOOP and HAS_CHAIN properties are set, reset the functions on
|
||||||
|
all pads.
|
||||||
|
(gst_fakesink_activate): Assert that the appropriate functions are
|
||||||
|
available for the activation mode.
|
||||||
|
(gst_fakesink_loop): Don't unref the buffer, chain_unlocked does
|
||||||
|
it for us.
|
||||||
|
|
||||||
2005-02-16 Wim Taymans <wim@fluendo.com>
|
2005-02-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/elements/gstfakesink.c: (gst_fakesink_activate),
|
* gst/elements/gstfakesink.c: (gst_fakesink_activate),
|
||||||
|
|
|
@ -61,7 +61,9 @@ enum
|
||||||
ARG_DUMP,
|
ARG_DUMP,
|
||||||
ARG_SYNC,
|
ARG_SYNC,
|
||||||
ARG_SIGNAL_HANDOFFS,
|
ARG_SIGNAL_HANDOFFS,
|
||||||
ARG_LAST_MESSAGE
|
ARG_LAST_MESSAGE,
|
||||||
|
ARG_HAS_LOOP,
|
||||||
|
ARG_HAS_CHAIN
|
||||||
};
|
};
|
||||||
|
|
||||||
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
|
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
|
||||||
|
@ -171,6 +173,14 @@ gst_fakesink_class_init (GstFakeSinkClass * klass)
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
|
||||||
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
|
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
|
||||||
FALSE, G_PARAM_READWRITE));
|
FALSE, G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_LOOP,
|
||||||
|
g_param_spec_boolean ("has-loop", "has-loop",
|
||||||
|
"Enable loop-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_CHAIN,
|
||||||
|
g_param_spec_boolean ("has-chain", "has-chain",
|
||||||
|
"Enable chain-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
||||||
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
|
@ -194,11 +204,6 @@ gst_fakesink_init (GstFakeSink * fakesink)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate),
|
||||||
"sink");
|
"sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
||||||
gst_pad_set_activate_function (pad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_fakesink_activate));
|
|
||||||
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
|
||||||
gst_pad_set_loop_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_loop));
|
|
||||||
gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
|
|
||||||
|
|
||||||
fakesink->silent = FALSE;
|
fakesink->silent = FALSE;
|
||||||
fakesink->dump = FALSE;
|
fakesink->dump = FALSE;
|
||||||
|
@ -210,6 +215,33 @@ gst_fakesink_init (GstFakeSink * fakesink)
|
||||||
GST_RPAD_TASK (pad) = NULL;
|
GST_RPAD_TASK (pad) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesink_set_pad_functions (GstFakeSink * this, GstPad * pad)
|
||||||
|
{
|
||||||
|
gst_pad_set_activate_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_fakesink_activate));
|
||||||
|
gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
|
||||||
|
|
||||||
|
if (this->has_chain)
|
||||||
|
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
||||||
|
else
|
||||||
|
gst_pad_set_chain_function (pad, NULL);
|
||||||
|
|
||||||
|
if (this->has_loop)
|
||||||
|
gst_pad_set_loop_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_loop));
|
||||||
|
else
|
||||||
|
gst_pad_set_loop_function (pad, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesink_set_all_pad_functions (GstFakeSink * this)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = GST_ELEMENT_PADS (this); l; l = l->next)
|
||||||
|
gst_fakesink_set_pad_functions (this, (GstPad *) l->data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fakesink_set_clock (GstElement * element, GstClock * clock)
|
gst_fakesink_set_clock (GstElement * element, GstClock * clock)
|
||||||
{
|
{
|
||||||
|
@ -241,8 +273,7 @@ gst_fakesink_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
|
|
||||||
sinkpad = gst_pad_new_from_template (templ, name);
|
sinkpad = gst_pad_new_from_template (templ, name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
gst_fakesink_set_pad_functions (fakesink, sinkpad);
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
|
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
|
||||||
|
|
||||||
return sinkpad;
|
return sinkpad;
|
||||||
|
@ -258,6 +289,14 @@ gst_fakesink_set_property (GObject * object, guint prop_id,
|
||||||
sink = GST_FAKESINK (object);
|
sink = GST_FAKESINK (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case ARG_HAS_LOOP:
|
||||||
|
sink->has_loop = g_value_get_boolean (value);
|
||||||
|
gst_fakesink_set_all_pad_functions (sink);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_CHAIN:
|
||||||
|
sink->has_chain = g_value_get_boolean (value);
|
||||||
|
gst_fakesink_set_all_pad_functions (sink);
|
||||||
|
break;
|
||||||
case ARG_SILENT:
|
case ARG_SILENT:
|
||||||
sink->silent = g_value_get_boolean (value);
|
sink->silent = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
@ -328,10 +367,12 @@ gst_fakesink_activate (GstPad * pad, GstActivateMode mode)
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GST_ACTIVATE_PUSH:
|
case GST_ACTIVATE_PUSH:
|
||||||
|
g_return_val_if_fail (fakesink->has_chain, FALSE);
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_PULL:
|
case GST_ACTIVATE_PULL:
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
|
g_return_val_if_fail (fakesink->has_loop, FALSE);
|
||||||
if (GST_ELEMENT_SCHEDULER (fakesink)) {
|
if (GST_ELEMENT_SCHEDULER (fakesink)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
GST_RPAD_TASK (pad) =
|
GST_RPAD_TASK (pad) =
|
||||||
|
@ -483,8 +524,6 @@ gst_fakesink_loop (GstPad * pad)
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
if (buf)
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
paused:
|
paused:
|
||||||
|
|
|
@ -60,6 +60,8 @@ struct _GstFakeSink {
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
gboolean dump;
|
gboolean dump;
|
||||||
|
gboolean has_loop;
|
||||||
|
gboolean has_chain;
|
||||||
gboolean sync;
|
gboolean sync;
|
||||||
gboolean signal_handoffs;
|
gboolean signal_handoffs;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
|
|
@ -64,7 +64,8 @@ enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_NUM_SOURCES,
|
ARG_NUM_SOURCES,
|
||||||
ARG_LOOP_BASED,
|
ARG_HAS_LOOP,
|
||||||
|
ARG_HAS_GETRANGE,
|
||||||
ARG_OUTPUT,
|
ARG_OUTPUT,
|
||||||
ARG_DATA,
|
ARG_DATA,
|
||||||
ARG_SIZETYPE,
|
ARG_SIZETYPE,
|
||||||
|
@ -179,7 +180,6 @@ GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT,
|
||||||
|
|
||||||
static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
|
static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
|
||||||
GstPadTemplate * templ, const gchar * unused);
|
GstPadTemplate * templ, const gchar * unused);
|
||||||
static void gst_fakesrc_update_functions (GstFakeSrc * src);
|
|
||||||
static gboolean gst_fakesrc_activate (GstPad * pad, GstActivateMode mode);
|
static gboolean gst_fakesrc_activate (GstPad * pad, GstActivateMode mode);
|
||||||
static void gst_fakesrc_set_property (GObject * object, guint prop_id,
|
static void gst_fakesrc_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
@ -190,6 +190,8 @@ static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock);
|
||||||
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
|
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
|
||||||
|
|
||||||
static void gst_fakesrc_loop (GstPad * pad);
|
static void gst_fakesrc_loop (GstPad * pad);
|
||||||
|
static GstFlowReturn gst_fakesrc_get_range (GstPad * pad, guint64 offset,
|
||||||
|
guint length, GstBuffer ** buf);
|
||||||
|
|
||||||
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
@ -220,9 +222,14 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
|
||||||
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
|
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
|
||||||
1, G_MAXINT, 1, G_PARAM_READABLE));
|
1, G_MAXINT, 1, G_PARAM_READABLE));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_LOOP,
|
||||||
g_param_spec_boolean ("loop-based", "loop-based",
|
g_param_spec_boolean ("has-loop", "has-loop",
|
||||||
"Enable loop-based operation", FALSE, G_PARAM_READWRITE));
|
"Enable loop-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_GETRANGE,
|
||||||
|
g_param_spec_boolean ("has-getrange", "has-getrange",
|
||||||
|
"Enable getrange-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
|
||||||
g_param_spec_enum ("output", "output", "Output method (currently unused)",
|
g_param_spec_enum ("output", "output", "Output method (currently unused)",
|
||||||
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
|
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
|
||||||
|
@ -300,9 +307,6 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
|
||||||
"src");
|
"src");
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
|
gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
|
||||||
|
|
||||||
fakesrc->loop_based = FALSE;
|
|
||||||
gst_fakesrc_update_functions (fakesrc);
|
|
||||||
|
|
||||||
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
||||||
fakesrc->segment_start = -1;
|
fakesrc->segment_start = -1;
|
||||||
fakesrc->segment_end = -1;
|
fakesrc->segment_end = -1;
|
||||||
|
@ -336,35 +340,6 @@ gst_fakesrc_set_clock (GstElement * element, GstClock * clock)
|
||||||
src->clock = clock;
|
src->clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstPad *
|
|
||||||
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|
||||||
const gchar * unused)
|
|
||||||
{
|
|
||||||
gchar *name;
|
|
||||||
GstPad *srcpad;
|
|
||||||
GstFakeSrc *fakesrc;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
|
|
||||||
|
|
||||||
if (templ->direction != GST_PAD_SRC) {
|
|
||||||
g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fakesrc = GST_FAKESRC (element);
|
|
||||||
|
|
||||||
name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
|
|
||||||
|
|
||||||
srcpad = gst_pad_new_from_template (templ, name);
|
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
|
|
||||||
gst_fakesrc_update_functions (fakesrc);
|
|
||||||
|
|
||||||
g_free (name);
|
|
||||||
|
|
||||||
return srcpad;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const GstFormat *
|
static const GstFormat *
|
||||||
gst_fakesrc_get_formats (GstPad * pad)
|
gst_fakesrc_get_formats (GstPad * pad)
|
||||||
{
|
{
|
||||||
|
@ -455,23 +430,61 @@ gst_fakesrc_event_handler (GstPad * pad, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fakesrc_update_functions (GstFakeSrc * src)
|
gst_fakesrc_set_pad_functions (GstFakeSrc * src, GstPad * pad)
|
||||||
{
|
{
|
||||||
GList *pads;
|
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
||||||
|
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
||||||
|
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||||
|
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||||
|
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
||||||
|
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
||||||
|
|
||||||
pads = GST_ELEMENT (src)->pads;
|
if (src->has_loop)
|
||||||
while (pads) {
|
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
|
||||||
|
|
||||||
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
|
||||||
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
||||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
else
|
||||||
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
gst_pad_set_loop_function (pad, NULL);
|
||||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
|
||||||
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
if (src->has_getrange)
|
||||||
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
gst_pad_set_getrange_function (pad, gst_fakesrc_get_range);
|
||||||
pads = g_list_next (pads);
|
else
|
||||||
|
gst_pad_set_getrange_function (pad, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesrc_set_all_pad_functions (GstFakeSrc * src)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = GST_ELEMENT_PADS (src); l; l = l->next)
|
||||||
|
gst_fakesrc_set_pad_functions (src, (GstPad *) l->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstPad *
|
||||||
|
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
|
const gchar * unused)
|
||||||
|
{
|
||||||
|
gchar *name;
|
||||||
|
GstPad *srcpad;
|
||||||
|
GstFakeSrc *fakesrc;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
|
||||||
|
|
||||||
|
if (templ->direction != GST_PAD_SRC) {
|
||||||
|
g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakesrc = GST_FAKESRC (element);
|
||||||
|
|
||||||
|
name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
|
||||||
|
|
||||||
|
srcpad = gst_pad_new_from_template (templ, name);
|
||||||
|
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
|
||||||
|
gst_fakesrc_set_pad_functions (fakesrc, srcpad);
|
||||||
|
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
return srcpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -493,13 +506,16 @@ gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
|
|
||||||
/* it's not null if we got it, but it might not be ours */
|
|
||||||
src = GST_FAKESRC (object);
|
src = GST_FAKESRC (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_LOOP_BASED:
|
case ARG_HAS_LOOP:
|
||||||
src->loop_based = g_value_get_boolean (value);
|
src->has_loop = g_value_get_boolean (value);
|
||||||
gst_fakesrc_update_functions (src);
|
gst_fakesrc_set_all_pad_functions (src);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_GETRANGE:
|
||||||
|
src->has_getrange = g_value_get_boolean (value);
|
||||||
|
gst_fakesrc_set_all_pad_functions (src);
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT:
|
case ARG_OUTPUT:
|
||||||
g_warning ("not yet implemented");
|
g_warning ("not yet implemented");
|
||||||
|
@ -577,8 +593,11 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case ARG_NUM_SOURCES:
|
case ARG_NUM_SOURCES:
|
||||||
g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
|
g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
|
||||||
break;
|
break;
|
||||||
case ARG_LOOP_BASED:
|
case ARG_HAS_LOOP:
|
||||||
g_value_set_boolean (value, src->loop_based);
|
g_value_set_boolean (value, src->has_loop);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_GETRANGE:
|
||||||
|
g_value_set_boolean (value, src->has_getrange);
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT:
|
case ARG_OUTPUT:
|
||||||
g_value_set_enum (value, src->output);
|
g_value_set_enum (value, src->output);
|
||||||
|
@ -771,34 +790,28 @@ gst_fakesrc_create_buffer (GstFakeSrc * src)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GstFlowReturn
|
||||||
gst_fakesrc_loop (GstPad * pad)
|
gst_fakesrc_get_range_unlocked (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** ret)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
GST_STREAM_LOCK (pad);
|
|
||||||
if (src->need_flush) {
|
|
||||||
src->need_flush = FALSE;
|
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_FLUSH));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src->buffer_count == src->segment_end) {
|
if (src->buffer_count == src->segment_end) {
|
||||||
if (src->segment_loop) {
|
if (src->segment_loop) {
|
||||||
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
|
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
|
||||||
} else {
|
} else {
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->rt_num_buffers == 0) {
|
if (src->rt_num_buffers == 0) {
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
} else {
|
} else {
|
||||||
if (src->rt_num_buffers > 0)
|
if (src->rt_num_buffers > 0)
|
||||||
src->rt_num_buffers--;
|
src->rt_num_buffers--;
|
||||||
|
@ -807,7 +820,7 @@ gst_fakesrc_loop (GstPad * pad)
|
||||||
if (src->eos) {
|
if (src->eos) {
|
||||||
GST_INFO ("fakesrc is setting eos on pad");
|
GST_INFO ("fakesrc is setting eos on pad");
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = gst_fakesrc_create_buffer (src);
|
buf = gst_fakesrc_create_buffer (src);
|
||||||
|
@ -846,6 +859,46 @@ gst_fakesrc_loop (GstPad * pad)
|
||||||
|
|
||||||
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
|
*ret = buf;
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_fakesrc_get_range (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** ret)
|
||||||
|
{
|
||||||
|
GstFlowReturn fret;
|
||||||
|
|
||||||
|
GST_STREAM_LOCK (pad);
|
||||||
|
|
||||||
|
fret = gst_fakesrc_get_range_unlocked (pad, offset, length, ret);
|
||||||
|
|
||||||
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstFakeSrc *src;
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
GST_STREAM_LOCK (pad);
|
||||||
|
if (src->need_flush) {
|
||||||
|
src->need_flush = FALSE;
|
||||||
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_FLUSH));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gst_fakesrc_get_range_unlocked (pad, src->buffer_count,
|
||||||
|
DEFAULT_SIZEMAX, &buf);
|
||||||
|
if (ret != GST_FLOW_OK) {
|
||||||
|
goto pause;
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_pad_push (pad, buf);
|
ret = gst_pad_push (pad, buf);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
goto pause;
|
goto pause;
|
||||||
|
@ -871,6 +924,7 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GST_ACTIVATE_PUSH:
|
case GST_ACTIVATE_PUSH:
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
|
g_return_val_if_fail (fakesrc->has_loop, FALSE);
|
||||||
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
fakesrc->task =
|
fakesrc->task =
|
||||||
|
@ -883,6 +937,8 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_PULL:
|
case GST_ACTIVATE_PULL:
|
||||||
|
g_return_val_if_fail (fakesrc->has_getrange, FALSE);
|
||||||
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_NONE:
|
case GST_ACTIVATE_NONE:
|
||||||
/* step 1, unblock clock sync (if any) */
|
/* step 1, unblock clock sync (if any) */
|
||||||
|
@ -890,9 +946,11 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
/* step 2, make sure streaming finishes */
|
/* step 2, make sure streaming finishes */
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
/* step 3, stop the task */
|
/* step 3, stop the task */
|
||||||
gst_task_stop (fakesrc->task);
|
if (fakesrc->task) {
|
||||||
gst_object_unref (GST_OBJECT (fakesrc->task));
|
gst_task_stop (fakesrc->task);
|
||||||
fakesrc->task = NULL;
|
gst_object_unref (GST_OBJECT (fakesrc->task));
|
||||||
|
fakesrc->task = NULL;
|
||||||
|
}
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
|
|
|
@ -76,7 +76,8 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass;
|
||||||
struct _GstFakeSrc {
|
struct _GstFakeSrc {
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
gboolean loop_based;
|
gboolean has_loop;
|
||||||
|
gboolean has_getrange;
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
|
|
||||||
GstTask *task;
|
GstTask *task;
|
||||||
|
|
|
@ -61,7 +61,9 @@ enum
|
||||||
ARG_DUMP,
|
ARG_DUMP,
|
||||||
ARG_SYNC,
|
ARG_SYNC,
|
||||||
ARG_SIGNAL_HANDOFFS,
|
ARG_SIGNAL_HANDOFFS,
|
||||||
ARG_LAST_MESSAGE
|
ARG_LAST_MESSAGE,
|
||||||
|
ARG_HAS_LOOP,
|
||||||
|
ARG_HAS_CHAIN
|
||||||
};
|
};
|
||||||
|
|
||||||
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
|
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
|
||||||
|
@ -171,6 +173,14 @@ gst_fakesink_class_init (GstFakeSinkClass * klass)
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
|
||||||
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
|
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
|
||||||
FALSE, G_PARAM_READWRITE));
|
FALSE, G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_LOOP,
|
||||||
|
g_param_spec_boolean ("has-loop", "has-loop",
|
||||||
|
"Enable loop-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_CHAIN,
|
||||||
|
g_param_spec_boolean ("has-chain", "has-chain",
|
||||||
|
"Enable chain-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
||||||
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
|
@ -194,11 +204,6 @@ gst_fakesink_init (GstFakeSink * fakesink)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate),
|
||||||
"sink");
|
"sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
||||||
gst_pad_set_activate_function (pad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_fakesink_activate));
|
|
||||||
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
|
||||||
gst_pad_set_loop_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_loop));
|
|
||||||
gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
|
|
||||||
|
|
||||||
fakesink->silent = FALSE;
|
fakesink->silent = FALSE;
|
||||||
fakesink->dump = FALSE;
|
fakesink->dump = FALSE;
|
||||||
|
@ -210,6 +215,33 @@ gst_fakesink_init (GstFakeSink * fakesink)
|
||||||
GST_RPAD_TASK (pad) = NULL;
|
GST_RPAD_TASK (pad) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesink_set_pad_functions (GstFakeSink * this, GstPad * pad)
|
||||||
|
{
|
||||||
|
gst_pad_set_activate_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_fakesink_activate));
|
||||||
|
gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
|
||||||
|
|
||||||
|
if (this->has_chain)
|
||||||
|
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
||||||
|
else
|
||||||
|
gst_pad_set_chain_function (pad, NULL);
|
||||||
|
|
||||||
|
if (this->has_loop)
|
||||||
|
gst_pad_set_loop_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_loop));
|
||||||
|
else
|
||||||
|
gst_pad_set_loop_function (pad, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesink_set_all_pad_functions (GstFakeSink * this)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = GST_ELEMENT_PADS (this); l; l = l->next)
|
||||||
|
gst_fakesink_set_pad_functions (this, (GstPad *) l->data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fakesink_set_clock (GstElement * element, GstClock * clock)
|
gst_fakesink_set_clock (GstElement * element, GstClock * clock)
|
||||||
{
|
{
|
||||||
|
@ -241,8 +273,7 @@ gst_fakesink_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
|
|
||||||
sinkpad = gst_pad_new_from_template (templ, name);
|
sinkpad = gst_pad_new_from_template (templ, name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
|
gst_fakesink_set_pad_functions (fakesink, sinkpad);
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
|
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
|
||||||
|
|
||||||
return sinkpad;
|
return sinkpad;
|
||||||
|
@ -258,6 +289,14 @@ gst_fakesink_set_property (GObject * object, guint prop_id,
|
||||||
sink = GST_FAKESINK (object);
|
sink = GST_FAKESINK (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case ARG_HAS_LOOP:
|
||||||
|
sink->has_loop = g_value_get_boolean (value);
|
||||||
|
gst_fakesink_set_all_pad_functions (sink);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_CHAIN:
|
||||||
|
sink->has_chain = g_value_get_boolean (value);
|
||||||
|
gst_fakesink_set_all_pad_functions (sink);
|
||||||
|
break;
|
||||||
case ARG_SILENT:
|
case ARG_SILENT:
|
||||||
sink->silent = g_value_get_boolean (value);
|
sink->silent = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
@ -328,10 +367,12 @@ gst_fakesink_activate (GstPad * pad, GstActivateMode mode)
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GST_ACTIVATE_PUSH:
|
case GST_ACTIVATE_PUSH:
|
||||||
|
g_return_val_if_fail (fakesink->has_chain, FALSE);
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_PULL:
|
case GST_ACTIVATE_PULL:
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
|
g_return_val_if_fail (fakesink->has_loop, FALSE);
|
||||||
if (GST_ELEMENT_SCHEDULER (fakesink)) {
|
if (GST_ELEMENT_SCHEDULER (fakesink)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
GST_RPAD_TASK (pad) =
|
GST_RPAD_TASK (pad) =
|
||||||
|
@ -483,8 +524,6 @@ gst_fakesink_loop (GstPad * pad)
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
if (buf)
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
paused:
|
paused:
|
||||||
|
|
|
@ -60,6 +60,8 @@ struct _GstFakeSink {
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
gboolean dump;
|
gboolean dump;
|
||||||
|
gboolean has_loop;
|
||||||
|
gboolean has_chain;
|
||||||
gboolean sync;
|
gboolean sync;
|
||||||
gboolean signal_handoffs;
|
gboolean signal_handoffs;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
|
|
@ -64,7 +64,8 @@ enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_NUM_SOURCES,
|
ARG_NUM_SOURCES,
|
||||||
ARG_LOOP_BASED,
|
ARG_HAS_LOOP,
|
||||||
|
ARG_HAS_GETRANGE,
|
||||||
ARG_OUTPUT,
|
ARG_OUTPUT,
|
||||||
ARG_DATA,
|
ARG_DATA,
|
||||||
ARG_SIZETYPE,
|
ARG_SIZETYPE,
|
||||||
|
@ -179,7 +180,6 @@ GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT,
|
||||||
|
|
||||||
static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
|
static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
|
||||||
GstPadTemplate * templ, const gchar * unused);
|
GstPadTemplate * templ, const gchar * unused);
|
||||||
static void gst_fakesrc_update_functions (GstFakeSrc * src);
|
|
||||||
static gboolean gst_fakesrc_activate (GstPad * pad, GstActivateMode mode);
|
static gboolean gst_fakesrc_activate (GstPad * pad, GstActivateMode mode);
|
||||||
static void gst_fakesrc_set_property (GObject * object, guint prop_id,
|
static void gst_fakesrc_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
@ -190,6 +190,8 @@ static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock);
|
||||||
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
|
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
|
||||||
|
|
||||||
static void gst_fakesrc_loop (GstPad * pad);
|
static void gst_fakesrc_loop (GstPad * pad);
|
||||||
|
static GstFlowReturn gst_fakesrc_get_range (GstPad * pad, guint64 offset,
|
||||||
|
guint length, GstBuffer ** buf);
|
||||||
|
|
||||||
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
@ -220,9 +222,14 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
|
||||||
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
|
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
|
||||||
1, G_MAXINT, 1, G_PARAM_READABLE));
|
1, G_MAXINT, 1, G_PARAM_READABLE));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_LOOP,
|
||||||
g_param_spec_boolean ("loop-based", "loop-based",
|
g_param_spec_boolean ("has-loop", "has-loop",
|
||||||
"Enable loop-based operation", FALSE, G_PARAM_READWRITE));
|
"Enable loop-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HAS_GETRANGE,
|
||||||
|
g_param_spec_boolean ("has-getrange", "has-getrange",
|
||||||
|
"Enable getrange-based operation", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
|
||||||
g_param_spec_enum ("output", "output", "Output method (currently unused)",
|
g_param_spec_enum ("output", "output", "Output method (currently unused)",
|
||||||
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
|
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
|
||||||
|
@ -300,9 +307,6 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
|
||||||
"src");
|
"src");
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
|
gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
|
||||||
|
|
||||||
fakesrc->loop_based = FALSE;
|
|
||||||
gst_fakesrc_update_functions (fakesrc);
|
|
||||||
|
|
||||||
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
||||||
fakesrc->segment_start = -1;
|
fakesrc->segment_start = -1;
|
||||||
fakesrc->segment_end = -1;
|
fakesrc->segment_end = -1;
|
||||||
|
@ -336,35 +340,6 @@ gst_fakesrc_set_clock (GstElement * element, GstClock * clock)
|
||||||
src->clock = clock;
|
src->clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstPad *
|
|
||||||
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|
||||||
const gchar * unused)
|
|
||||||
{
|
|
||||||
gchar *name;
|
|
||||||
GstPad *srcpad;
|
|
||||||
GstFakeSrc *fakesrc;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
|
|
||||||
|
|
||||||
if (templ->direction != GST_PAD_SRC) {
|
|
||||||
g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fakesrc = GST_FAKESRC (element);
|
|
||||||
|
|
||||||
name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
|
|
||||||
|
|
||||||
srcpad = gst_pad_new_from_template (templ, name);
|
|
||||||
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
|
|
||||||
gst_fakesrc_update_functions (fakesrc);
|
|
||||||
|
|
||||||
g_free (name);
|
|
||||||
|
|
||||||
return srcpad;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const GstFormat *
|
static const GstFormat *
|
||||||
gst_fakesrc_get_formats (GstPad * pad)
|
gst_fakesrc_get_formats (GstPad * pad)
|
||||||
{
|
{
|
||||||
|
@ -455,23 +430,61 @@ gst_fakesrc_event_handler (GstPad * pad, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fakesrc_update_functions (GstFakeSrc * src)
|
gst_fakesrc_set_pad_functions (GstFakeSrc * src, GstPad * pad)
|
||||||
{
|
{
|
||||||
GList *pads;
|
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
||||||
|
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
||||||
|
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||||
|
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||||
|
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
||||||
|
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
||||||
|
|
||||||
pads = GST_ELEMENT (src)->pads;
|
if (src->has_loop)
|
||||||
while (pads) {
|
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
|
||||||
|
|
||||||
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
|
||||||
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
||||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
else
|
||||||
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
gst_pad_set_loop_function (pad, NULL);
|
||||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
|
||||||
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
if (src->has_getrange)
|
||||||
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
gst_pad_set_getrange_function (pad, gst_fakesrc_get_range);
|
||||||
pads = g_list_next (pads);
|
else
|
||||||
|
gst_pad_set_getrange_function (pad, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesrc_set_all_pad_functions (GstFakeSrc * src)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = GST_ELEMENT_PADS (src); l; l = l->next)
|
||||||
|
gst_fakesrc_set_pad_functions (src, (GstPad *) l->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstPad *
|
||||||
|
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
|
const gchar * unused)
|
||||||
|
{
|
||||||
|
gchar *name;
|
||||||
|
GstPad *srcpad;
|
||||||
|
GstFakeSrc *fakesrc;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
|
||||||
|
|
||||||
|
if (templ->direction != GST_PAD_SRC) {
|
||||||
|
g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakesrc = GST_FAKESRC (element);
|
||||||
|
|
||||||
|
name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
|
||||||
|
|
||||||
|
srcpad = gst_pad_new_from_template (templ, name);
|
||||||
|
gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
|
||||||
|
gst_fakesrc_set_pad_functions (fakesrc, srcpad);
|
||||||
|
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
return srcpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -493,13 +506,16 @@ gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
|
|
||||||
/* it's not null if we got it, but it might not be ours */
|
|
||||||
src = GST_FAKESRC (object);
|
src = GST_FAKESRC (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_LOOP_BASED:
|
case ARG_HAS_LOOP:
|
||||||
src->loop_based = g_value_get_boolean (value);
|
src->has_loop = g_value_get_boolean (value);
|
||||||
gst_fakesrc_update_functions (src);
|
gst_fakesrc_set_all_pad_functions (src);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_GETRANGE:
|
||||||
|
src->has_getrange = g_value_get_boolean (value);
|
||||||
|
gst_fakesrc_set_all_pad_functions (src);
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT:
|
case ARG_OUTPUT:
|
||||||
g_warning ("not yet implemented");
|
g_warning ("not yet implemented");
|
||||||
|
@ -577,8 +593,11 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case ARG_NUM_SOURCES:
|
case ARG_NUM_SOURCES:
|
||||||
g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
|
g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
|
||||||
break;
|
break;
|
||||||
case ARG_LOOP_BASED:
|
case ARG_HAS_LOOP:
|
||||||
g_value_set_boolean (value, src->loop_based);
|
g_value_set_boolean (value, src->has_loop);
|
||||||
|
break;
|
||||||
|
case ARG_HAS_GETRANGE:
|
||||||
|
g_value_set_boolean (value, src->has_getrange);
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT:
|
case ARG_OUTPUT:
|
||||||
g_value_set_enum (value, src->output);
|
g_value_set_enum (value, src->output);
|
||||||
|
@ -771,34 +790,28 @@ gst_fakesrc_create_buffer (GstFakeSrc * src)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GstFlowReturn
|
||||||
gst_fakesrc_loop (GstPad * pad)
|
gst_fakesrc_get_range_unlocked (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** ret)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
GST_STREAM_LOCK (pad);
|
|
||||||
if (src->need_flush) {
|
|
||||||
src->need_flush = FALSE;
|
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_FLUSH));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src->buffer_count == src->segment_end) {
|
if (src->buffer_count == src->segment_end) {
|
||||||
if (src->segment_loop) {
|
if (src->segment_loop) {
|
||||||
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
|
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
|
||||||
} else {
|
} else {
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->rt_num_buffers == 0) {
|
if (src->rt_num_buffers == 0) {
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
} else {
|
} else {
|
||||||
if (src->rt_num_buffers > 0)
|
if (src->rt_num_buffers > 0)
|
||||||
src->rt_num_buffers--;
|
src->rt_num_buffers--;
|
||||||
|
@ -807,7 +820,7 @@ gst_fakesrc_loop (GstPad * pad)
|
||||||
if (src->eos) {
|
if (src->eos) {
|
||||||
GST_INFO ("fakesrc is setting eos on pad");
|
GST_INFO ("fakesrc is setting eos on pad");
|
||||||
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
|
||||||
goto pause;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = gst_fakesrc_create_buffer (src);
|
buf = gst_fakesrc_create_buffer (src);
|
||||||
|
@ -846,6 +859,46 @@ gst_fakesrc_loop (GstPad * pad)
|
||||||
|
|
||||||
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
|
*ret = buf;
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_fakesrc_get_range (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** ret)
|
||||||
|
{
|
||||||
|
GstFlowReturn fret;
|
||||||
|
|
||||||
|
GST_STREAM_LOCK (pad);
|
||||||
|
|
||||||
|
fret = gst_fakesrc_get_range_unlocked (pad, offset, length, ret);
|
||||||
|
|
||||||
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstFakeSrc *src;
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
GST_STREAM_LOCK (pad);
|
||||||
|
if (src->need_flush) {
|
||||||
|
src->need_flush = FALSE;
|
||||||
|
gst_pad_push_event (pad, gst_event_new (GST_EVENT_FLUSH));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gst_fakesrc_get_range_unlocked (pad, src->buffer_count,
|
||||||
|
DEFAULT_SIZEMAX, &buf);
|
||||||
|
if (ret != GST_FLOW_OK) {
|
||||||
|
goto pause;
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_pad_push (pad, buf);
|
ret = gst_pad_push (pad, buf);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
goto pause;
|
goto pause;
|
||||||
|
@ -871,6 +924,7 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GST_ACTIVATE_PUSH:
|
case GST_ACTIVATE_PUSH:
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
|
g_return_val_if_fail (fakesrc->has_loop, FALSE);
|
||||||
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
fakesrc->task =
|
fakesrc->task =
|
||||||
|
@ -883,6 +937,8 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_PULL:
|
case GST_ACTIVATE_PULL:
|
||||||
|
g_return_val_if_fail (fakesrc->has_getrange, FALSE);
|
||||||
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_ACTIVATE_NONE:
|
case GST_ACTIVATE_NONE:
|
||||||
/* step 1, unblock clock sync (if any) */
|
/* step 1, unblock clock sync (if any) */
|
||||||
|
@ -890,9 +946,11 @@ gst_fakesrc_activate (GstPad * pad, GstActivateMode mode)
|
||||||
/* step 2, make sure streaming finishes */
|
/* step 2, make sure streaming finishes */
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
/* step 3, stop the task */
|
/* step 3, stop the task */
|
||||||
gst_task_stop (fakesrc->task);
|
if (fakesrc->task) {
|
||||||
gst_object_unref (GST_OBJECT (fakesrc->task));
|
gst_task_stop (fakesrc->task);
|
||||||
fakesrc->task = NULL;
|
gst_object_unref (GST_OBJECT (fakesrc->task));
|
||||||
|
fakesrc->task = NULL;
|
||||||
|
}
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
|
|
|
@ -76,7 +76,8 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass;
|
||||||
struct _GstFakeSrc {
|
struct _GstFakeSrc {
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
gboolean loop_based;
|
gboolean has_loop;
|
||||||
|
gboolean has_getrange;
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
|
|
||||||
GstTask *task;
|
GstTask *task;
|
||||||
|
|
Loading…
Reference in a new issue