mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 11:10:37 +00:00
docs/design/part-negotiation.txt: Small doc update.
Original commit message from CVS: * docs/design/part-negotiation.txt: Small doc update. * docs/libs/gstreamer-libs-sections.txt: * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_pad_getcaps), (gst_base_sink_pad_setcaps), (gst_base_sink_init), (gst_base_sink_set_blocksize), (gst_base_sink_get_blocksize), (gst_base_sink_set_property), (gst_base_sink_get_property), (gst_base_sink_needs_preroll), (gst_base_sink_loop), (gst_base_sink_pad_activate), (gst_base_sink_negotiate_pull), (gst_base_sink_pad_activate_pull), (gst_base_sink_change_state): * libs/gst/base/gstbasesink.h: Add blocksize property and methods to control the amount of data to pull. Negotiate first before activating upstream in pull mode so that they can negotiate themselves. When we operate in pull mode, we only accept the caps that we negotiated. Make the sink go ASYNC to PAUSED, like all other sinks. API: GstBaseSink::gst_base_sink_set_blocksize() API: GstBaseSink::gst_base_sink_get_blocksize() API: GstBaseSink::blocksize * libs/gst/base/gstbasesrc.c: (gst_base_src_wait_playing), (gst_base_src_set_live), (gst_base_src_is_live), (gst_base_src_set_format), (gst_base_src_query_latency), (gst_base_src_set_blocksize), (gst_base_src_get_blocksize), (gst_base_src_set_do_timestamp), (gst_base_src_get_do_timestamp), (gst_base_src_set_property), (gst_base_src_get_property): * libs/gst/base/gstbasesrc.h: Add typechecking in public API functions. Add methods to control the blocksize in subclasses. API: GstBaseSrc::gst_base_src_set_blocksize() API: GstBaseSrc::gst_base_src_get_blocksize()
This commit is contained in:
parent
3159228799
commit
b3403511ea
7 changed files with 277 additions and 83 deletions
38
ChangeLog
38
ChangeLog
|
@ -1,3 +1,41 @@
|
|||
2008-10-10 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* docs/design/part-negotiation.txt:
|
||||
Small doc update.
|
||||
|
||||
* docs/libs/gstreamer-libs-sections.txt:
|
||||
* libs/gst/base/gstbasesink.c: (gst_base_sink_class_init),
|
||||
(gst_base_sink_pad_getcaps), (gst_base_sink_pad_setcaps),
|
||||
(gst_base_sink_init), (gst_base_sink_set_blocksize),
|
||||
(gst_base_sink_get_blocksize), (gst_base_sink_set_property),
|
||||
(gst_base_sink_get_property), (gst_base_sink_needs_preroll),
|
||||
(gst_base_sink_loop), (gst_base_sink_pad_activate),
|
||||
(gst_base_sink_negotiate_pull), (gst_base_sink_pad_activate_pull),
|
||||
(gst_base_sink_change_state):
|
||||
* libs/gst/base/gstbasesink.h:
|
||||
Add blocksize property and methods to control the amount of data
|
||||
to pull.
|
||||
Negotiate first before activating upstream in pull mode so that they can
|
||||
negotiate themselves.
|
||||
When we operate in pull mode, we only accept the caps that we
|
||||
negotiated.
|
||||
Make the sink go ASYNC to PAUSED, like all other sinks.
|
||||
API: GstBaseSink::gst_base_sink_set_blocksize()
|
||||
API: GstBaseSink::gst_base_sink_get_blocksize()
|
||||
API: GstBaseSink::blocksize
|
||||
|
||||
* libs/gst/base/gstbasesrc.c: (gst_base_src_wait_playing),
|
||||
(gst_base_src_set_live), (gst_base_src_is_live),
|
||||
(gst_base_src_set_format), (gst_base_src_query_latency),
|
||||
(gst_base_src_set_blocksize), (gst_base_src_get_blocksize),
|
||||
(gst_base_src_set_do_timestamp), (gst_base_src_get_do_timestamp),
|
||||
(gst_base_src_set_property), (gst_base_src_get_property):
|
||||
* libs/gst/base/gstbasesrc.h:
|
||||
Add typechecking in public API functions.
|
||||
Add methods to control the blocksize in subclasses.
|
||||
API: GstBaseSrc::gst_base_src_set_blocksize()
|
||||
API: GstBaseSrc::gst_base_src_get_blocksize()
|
||||
|
||||
2008-10-10 Edward Hervey <edward.hervey@collabora.co.uk>
|
||||
|
||||
* tests/check/gst/gstutils.c: (probe_do_nothing), (data_probe),
|
||||
|
|
|
@ -37,7 +37,8 @@ The basics of negotiation are as follows:
|
|||
the buffer has changed. The element should reconfigure itself to the
|
||||
new format before processing the buffer data. If the data type on
|
||||
the buffer is not acceptable, the element should refuse the buffer by
|
||||
returning an appropriate return value from the chain function.
|
||||
returning an appropriate GST_FLOW_NOT_NEGOTIATED return value from the
|
||||
chain function.
|
||||
The core will automatically call the set_caps function for this purpose
|
||||
when it is installed on the sink or source pad.
|
||||
|
||||
|
|
|
@ -230,6 +230,8 @@ gst_base_src_is_live
|
|||
gst_base_src_set_live
|
||||
gst_base_src_set_format
|
||||
gst_base_src_query_latency
|
||||
gst_base_src_get_blocksize
|
||||
gst_base_src_set_blocksize
|
||||
gst_base_src_get_do_timestamp
|
||||
gst_base_src_set_do_timestamp
|
||||
|
||||
|
@ -272,6 +274,8 @@ gst_base_sink_get_ts_offset
|
|||
gst_base_sink_set_render_delay
|
||||
gst_base_sink_get_render_delay
|
||||
gst_base_sink_get_last_buffer
|
||||
gst_base_sink_set_blocksize
|
||||
gst_base_sink_get_blocksize
|
||||
|
||||
GST_BASE_SINK_PAD
|
||||
|
||||
|
|
|
@ -211,6 +211,11 @@ struct _GstBaseSinkPrivate
|
|||
|
||||
/* the last buffer we prerolled or rendered. Useful for making snapshots */
|
||||
GstBuffer *last_buffer;
|
||||
|
||||
/* caps for pull based scheduling */
|
||||
GstCaps *pull_caps;
|
||||
|
||||
guint blocksize;
|
||||
};
|
||||
|
||||
#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
|
||||
|
@ -226,7 +231,6 @@ struct _GstBaseSinkPrivate
|
|||
|
||||
/* BaseSink properties */
|
||||
|
||||
#define DEFAULT_SIZE 1024
|
||||
#define DEFAULT_CAN_ACTIVATE_PULL FALSE /* fixme: enable me */
|
||||
#define DEFAULT_CAN_ACTIVATE_PUSH TRUE
|
||||
|
||||
|
@ -236,6 +240,7 @@ struct _GstBaseSinkPrivate
|
|||
#define DEFAULT_QOS FALSE
|
||||
#define DEFAULT_ASYNC TRUE
|
||||
#define DEFAULT_TS_OFFSET 0
|
||||
#define DEFAULT_BLOCKSIZE 4096
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -247,6 +252,7 @@ enum
|
|||
PROP_ASYNC,
|
||||
PROP_TS_OFFSET,
|
||||
PROP_LAST_BUFFER,
|
||||
PROP_BLOCKSIZE,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
|
@ -311,6 +317,8 @@ static gboolean gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active);
|
|||
static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_base_sink_peer_query (GstBaseSink * sink, GstQuery * query);
|
||||
|
||||
static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
|
||||
|
||||
/* check if an object was too late */
|
||||
static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
|
||||
GstMiniObject * obj, GstClockTime start, GstClockTime stop,
|
||||
|
@ -400,6 +408,18 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
|
|||
"The last buffer received in the sink", GST_TYPE_BUFFER,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstBaseSink:blocksize
|
||||
*
|
||||
* The amount of bytes to pull when operating in pull mode.
|
||||
*
|
||||
* Since: 0.10.22
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
|
||||
g_param_spec_uint ("blocksize", "Block size",
|
||||
"Size in bytes to pull per buffer (0 = default)", 0, G_MAXUINT,
|
||||
DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_base_sink_change_state);
|
||||
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_sink_send_event);
|
||||
|
@ -422,16 +442,27 @@ gst_base_sink_pad_getcaps (GstPad * pad)
|
|||
|
||||
bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
||||
bclass = GST_BASE_SINK_GET_CLASS (bsink);
|
||||
if (bclass->get_caps)
|
||||
caps = bclass->get_caps (bsink);
|
||||
|
||||
if (bsink->pad_mode == GST_ACTIVATE_PULL) {
|
||||
/* if we are operating in pull mode we only accept the negotiated caps */
|
||||
GST_OBJECT_LOCK (pad);
|
||||
if ((caps = GST_PAD_CAPS (pad)))
|
||||
gst_caps_ref (caps);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
}
|
||||
if (caps == NULL) {
|
||||
GstPadTemplate *pad_template;
|
||||
if (bclass->get_caps)
|
||||
caps = bclass->get_caps (bsink);
|
||||
|
||||
pad_template =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
|
||||
if (pad_template != NULL) {
|
||||
caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
|
||||
if (caps == NULL) {
|
||||
GstPadTemplate *pad_template;
|
||||
|
||||
pad_template =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass),
|
||||
"sink");
|
||||
if (pad_template != NULL) {
|
||||
caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_object_unref (bsink);
|
||||
|
@ -449,18 +480,6 @@ gst_base_sink_pad_setcaps (GstPad * pad, GstCaps * caps)
|
|||
bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
||||
bclass = GST_BASE_SINK_GET_CLASS (bsink);
|
||||
|
||||
if (bsink->pad_mode == GST_ACTIVATE_PULL) {
|
||||
GstPad *peer = gst_pad_get_peer (pad);
|
||||
|
||||
if (peer)
|
||||
res = gst_pad_set_caps (peer, caps);
|
||||
else
|
||||
res = FALSE;
|
||||
|
||||
if (!res)
|
||||
GST_DEBUG_OBJECT (bsink, "peer setcaps() failed");
|
||||
}
|
||||
|
||||
if (res && bclass->set_caps)
|
||||
res = bclass->set_caps (bsink, caps);
|
||||
|
||||
|
@ -553,6 +572,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
|
|||
priv->async_enabled = DEFAULT_ASYNC;
|
||||
priv->ts_offset = DEFAULT_TS_OFFSET;
|
||||
priv->render_delay = 0;
|
||||
priv->blocksize = DEFAULT_BLOCKSIZE;
|
||||
|
||||
GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
|
||||
}
|
||||
|
@ -1029,6 +1049,52 @@ gst_base_sink_get_render_delay (GstBaseSink * sink)
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_base_sink_set_blocksize:
|
||||
* @sink: a #GstBaseSink
|
||||
* @blocksize: the blocksize in bytes
|
||||
*
|
||||
* Set the number of bytes that the sink will pull when it is operating in pull
|
||||
* mode.
|
||||
*
|
||||
* Since: 0.10.22
|
||||
*/
|
||||
void
|
||||
gst_base_sink_set_blocksize (GstBaseSink * sink, guint blocksize)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BASE_SINK (sink));
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
sink->priv->blocksize = blocksize;
|
||||
GST_LOG_OBJECT (sink, "set blocksize to %u", blocksize);
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_base_sink_get_blocksize:
|
||||
* @sink: a #GstBaseSink
|
||||
*
|
||||
* Get the number of bytes that the sink will pull when it is operating in pull
|
||||
* mode.
|
||||
*
|
||||
* Returns: the number of bytes @sink will pull in pull mode.
|
||||
*
|
||||
* Since: 0.10.22
|
||||
*/
|
||||
guint
|
||||
gst_base_sink_get_blocksize (GstBaseSink * sink)
|
||||
{
|
||||
guint res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
res = sink->priv->blocksize;
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -1057,6 +1123,9 @@ gst_base_sink_set_property (GObject * object, guint prop_id,
|
|||
case PROP_TS_OFFSET:
|
||||
gst_base_sink_set_ts_offset (sink, g_value_get_int64 (value));
|
||||
break;
|
||||
case PROP_BLOCKSIZE:
|
||||
gst_base_sink_set_blocksize (sink, g_value_get_uint (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1093,6 +1162,9 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_LAST_BUFFER:
|
||||
gst_value_take_buffer (value, gst_base_sink_get_last_buffer (sink));
|
||||
break;
|
||||
case PROP_BLOCKSIZE:
|
||||
g_value_set_uint (value, gst_base_sink_get_blocksize (sink));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -2649,7 +2721,8 @@ gst_base_sink_needs_preroll (GstBaseSink * basesink)
|
|||
* 2) we are syncing on the clock
|
||||
*/
|
||||
is_prerolled = basesink->have_preroll || basesink->priv->received_eos;
|
||||
res = !is_prerolled && basesink->pad_mode != GST_ACTIVATE_PULL;
|
||||
res = !is_prerolled;
|
||||
|
||||
GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d => needs preroll: %d",
|
||||
basesink->have_preroll, basesink->priv->received_eos, res);
|
||||
|
||||
|
@ -2799,15 +2872,19 @@ gst_base_sink_loop (GstPad * pad)
|
|||
GstBaseSink *basesink;
|
||||
GstBuffer *buf = NULL;
|
||||
GstFlowReturn result;
|
||||
guint blocksize;
|
||||
|
||||
basesink = GST_BASE_SINK (GST_OBJECT_PARENT (pad));
|
||||
|
||||
g_assert (basesink->pad_mode == GST_ACTIVATE_PULL);
|
||||
|
||||
GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
|
||||
basesink->offset, (guint) DEFAULT_SIZE);
|
||||
if ((blocksize = basesink->priv->blocksize) == 0)
|
||||
blocksize = -1;
|
||||
|
||||
result = gst_pad_pull_range (pad, basesink->offset, DEFAULT_SIZE, &buf);
|
||||
GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
|
||||
basesink->offset, blocksize);
|
||||
|
||||
result = gst_pad_pull_range (pad, basesink->offset, blocksize, &buf);
|
||||
if (G_UNLIKELY (result != GST_FLOW_OK))
|
||||
goto paused;
|
||||
|
||||
|
@ -2922,18 +2999,45 @@ gst_base_sink_pad_activate (GstPad * pad)
|
|||
|
||||
gst_base_sink_set_flushing (basesink, pad, FALSE);
|
||||
|
||||
if (basesink->can_activate_pull && gst_pad_check_pull_range (pad)
|
||||
&& gst_pad_activate_pull (pad, TRUE)) {
|
||||
GST_DEBUG_OBJECT (basesink, "Success activating pull mode");
|
||||
result = TRUE;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (basesink, "Falling back to push mode");
|
||||
if (gst_pad_activate_push (pad, TRUE)) {
|
||||
GST_DEBUG_OBJECT (basesink, "Success activating push mode");
|
||||
result = TRUE;
|
||||
}
|
||||
/* we need to have the pull mode enabled */
|
||||
if (!basesink->can_activate_pull)
|
||||
goto fallback;
|
||||
|
||||
/* check if downstreams supports pull mode at all */
|
||||
if (!gst_pad_check_pull_range (pad))
|
||||
goto fallback;
|
||||
|
||||
/* set the pad mode before starting the task so that it's in the
|
||||
* correct state for the new thread. also the sink set_caps and get_caps
|
||||
* function checks this */
|
||||
basesink->pad_mode = GST_ACTIVATE_PULL;
|
||||
|
||||
/* we first try to negotiate a format so that when we try to activate
|
||||
* downstream, it knows about our format */
|
||||
if (!gst_base_sink_negotiate_pull (basesink))
|
||||
goto fallback;
|
||||
|
||||
/* ok activate now */
|
||||
if (!gst_pad_activate_pull (pad, TRUE)) {
|
||||
/* clear any pending caps */
|
||||
GST_OBJECT_LOCK (basesink);
|
||||
gst_caps_replace (&basesink->priv->pull_caps, NULL);
|
||||
GST_OBJECT_UNLOCK (basesink);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (basesink, "Success activating pull mode");
|
||||
result = TRUE;
|
||||
goto done;
|
||||
|
||||
/* push mode fallback */
|
||||
fallback:
|
||||
GST_DEBUG_OBJECT (basesink, "Falling back to push mode");
|
||||
if ((result = gst_pad_activate_push (pad, TRUE))) {
|
||||
GST_DEBUG_OBJECT (basesink, "Success activating push mode");
|
||||
}
|
||||
|
||||
done:
|
||||
if (!result) {
|
||||
GST_WARNING_OBJECT (basesink, "Could not activate pad in either mode");
|
||||
gst_base_sink_set_flushing (basesink, pad, TRUE);
|
||||
|
@ -3010,6 +3114,11 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
|
|||
} else if (gst_caps_is_fixed (caps)) {
|
||||
if (!gst_pad_set_caps (GST_BASE_SINK_PAD (basesink), caps))
|
||||
goto could_not_set_caps;
|
||||
|
||||
GST_OBJECT_LOCK (basesink);
|
||||
gst_caps_replace (&basesink->priv->pull_caps, caps);
|
||||
GST_OBJECT_UNLOCK (basesink);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
|
@ -3045,49 +3154,23 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
|
|||
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
||||
|
||||
if (active) {
|
||||
if (!basesink->can_activate_pull) {
|
||||
/* we mark we have a newsegment here because pull based
|
||||
* mode works just fine without having a newsegment before the
|
||||
* first buffer */
|
||||
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
|
||||
gst_segment_init (basesink->abidata.ABI.clip_segment, GST_FORMAT_UNDEFINED);
|
||||
GST_OBJECT_LOCK (basesink);
|
||||
basesink->have_newsegment = TRUE;
|
||||
GST_OBJECT_UNLOCK (basesink);
|
||||
|
||||
if (bclass->activate_pull)
|
||||
result = bclass->activate_pull (basesink, TRUE);
|
||||
else
|
||||
result = FALSE;
|
||||
|
||||
/* but if starting the thread fails, set it back */
|
||||
if (!result)
|
||||
basesink->pad_mode = GST_ACTIVATE_NONE;
|
||||
} else {
|
||||
GstPad *peer = gst_pad_get_peer (pad);
|
||||
|
||||
if (G_UNLIKELY (peer == NULL)) {
|
||||
g_warning ("Trying to activate pad in pull mode, but no peer");
|
||||
result = FALSE;
|
||||
basesink->pad_mode = GST_ACTIVATE_NONE;
|
||||
} else {
|
||||
if (gst_pad_activate_pull (peer, TRUE)) {
|
||||
/* we mark we have a newsegment here because pull based
|
||||
* mode works just fine without having a newsegment before the
|
||||
* first buffer */
|
||||
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
|
||||
gst_segment_init (basesink->abidata.ABI.clip_segment,
|
||||
GST_FORMAT_UNDEFINED);
|
||||
GST_OBJECT_LOCK (basesink);
|
||||
basesink->have_newsegment = TRUE;
|
||||
GST_OBJECT_UNLOCK (basesink);
|
||||
|
||||
/* set the pad mode before starting the task so that it's in the
|
||||
correct state for the new thread. also the sink set_caps function
|
||||
checks this */
|
||||
basesink->pad_mode = GST_ACTIVATE_PULL;
|
||||
if ((result = gst_base_sink_negotiate_pull (basesink))) {
|
||||
if (bclass->activate_pull)
|
||||
result = bclass->activate_pull (basesink, TRUE);
|
||||
else
|
||||
result = FALSE;
|
||||
}
|
||||
/* but if starting the thread fails, set it back */
|
||||
if (!result)
|
||||
basesink->pad_mode = GST_ACTIVATE_NONE;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "Failed to activate peer in pull mode");
|
||||
result = FALSE;
|
||||
basesink->pad_mode = GST_ACTIVATE_NONE;
|
||||
}
|
||||
gst_object_unref (peer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (G_UNLIKELY (basesink->pad_mode != GST_ACTIVATE_PULL)) {
|
||||
g_warning ("Internal GStreamer activation error!!!");
|
||||
|
@ -3097,9 +3180,12 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
|
|||
if (bclass->activate_pull)
|
||||
result &= bclass->activate_pull (basesink, FALSE);
|
||||
basesink->pad_mode = GST_ACTIVATE_NONE;
|
||||
/* clear any pending caps */
|
||||
GST_OBJECT_LOCK (basesink);
|
||||
gst_caps_replace (&basesink->priv->pull_caps, NULL);
|
||||
GST_OBJECT_UNLOCK (basesink);
|
||||
}
|
||||
}
|
||||
|
||||
gst_object_unref (basesink);
|
||||
|
||||
return result;
|
||||
|
@ -3529,6 +3615,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
#if 0
|
||||
/* note that this is the upward case, which doesn't follow most
|
||||
patterns */
|
||||
if (basesink->pad_mode == GST_ACTIVATE_PULL) {
|
||||
|
@ -3540,6 +3627,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
|
||||
ret = GST_STATE_CHANGE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||
GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED");
|
||||
|
|
|
@ -221,6 +221,9 @@ GstClockTime gst_base_sink_get_latency (GstBaseSink *sink);
|
|||
void gst_base_sink_set_render_delay (GstBaseSink *sink, GstClockTime delay);
|
||||
GstClockTime gst_base_sink_get_render_delay (GstBaseSink *sink);
|
||||
|
||||
/* blocksize */
|
||||
void gst_base_sink_set_blocksize (GstBaseSink *sink, guint blocksize);
|
||||
guint gst_base_sink_get_blocksize (GstBaseSink *sink);
|
||||
|
||||
GstClockReturn gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
|
||||
GstClockTimeDiff * jitter);
|
||||
|
|
|
@ -455,6 +455,8 @@ gst_base_src_finalize (GObject * object)
|
|||
GstFlowReturn
|
||||
gst_base_src_wait_playing (GstBaseSrc * src)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), GST_FLOW_ERROR);
|
||||
|
||||
/* block until the state changes, or we get a flush, or something */
|
||||
GST_DEBUG_OBJECT (src, "live source waiting for running state");
|
||||
GST_LIVE_WAIT (src);
|
||||
|
@ -489,6 +491,8 @@ flushing:
|
|||
void
|
||||
gst_base_src_set_live (GstBaseSrc * src, gboolean live)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BASE_SRC (src));
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
src->is_live = live;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
@ -507,6 +511,8 @@ gst_base_src_is_live (GstBaseSrc * src)
|
|||
{
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
result = src->is_live;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
@ -530,6 +536,8 @@ gst_base_src_is_live (GstBaseSrc * src)
|
|||
void
|
||||
gst_base_src_set_format (GstBaseSrc * src, GstFormat format)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BASE_SRC (src));
|
||||
|
||||
gst_segment_init (&src->segment, format);
|
||||
}
|
||||
|
||||
|
@ -557,6 +565,8 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
|
|||
{
|
||||
GstClockTime min;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
if (live)
|
||||
*live = src->is_live;
|
||||
|
@ -582,6 +592,50 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_base_src_set_blocksize:
|
||||
* @src: the source
|
||||
* @blocksize: the new blocksize in bytes
|
||||
*
|
||||
* Set the number of bytes that @src will push out with each buffer.
|
||||
*
|
||||
* Since: 0.10.22
|
||||
*/
|
||||
void
|
||||
gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BASE_SRC (src));
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
src->blocksize = blocksize;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_base_src_get_blocksize:
|
||||
* @src: the source
|
||||
*
|
||||
* Get the number of bytes that @src will push out with each buffer.
|
||||
*
|
||||
* Returns: the number of bytes pushed with each buffer.
|
||||
*
|
||||
* Since: 0.10.22
|
||||
*/
|
||||
gulong
|
||||
gst_base_src_get_blocksize (GstBaseSrc * src)
|
||||
{
|
||||
gulong res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
res = src->blocksize;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_base_src_set_do_timestamp:
|
||||
* @src: the source
|
||||
|
@ -596,6 +650,8 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
|
|||
void
|
||||
gst_base_src_set_do_timestamp (GstBaseSrc * src, gboolean timestamp)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BASE_SRC (src));
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
src->priv->do_timestamp = timestamp;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
@ -616,6 +672,8 @@ gst_base_src_get_do_timestamp (GstBaseSrc * src)
|
|||
{
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
res = src->priv->do_timestamp;
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
@ -1513,7 +1571,7 @@ gst_base_src_set_property (GObject * object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_BLOCKSIZE:
|
||||
src->blocksize = g_value_get_ulong (value);
|
||||
gst_base_src_set_blocksize (src, g_value_get_ulong (value));
|
||||
break;
|
||||
case PROP_NUM_BUFFERS:
|
||||
src->num_buffers = g_value_get_int (value);
|
||||
|
@ -1522,7 +1580,7 @@ gst_base_src_set_property (GObject * object, guint prop_id,
|
|||
src->data.ABI.typefind = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_DO_TIMESTAMP:
|
||||
src->priv->do_timestamp = g_value_get_boolean (value);
|
||||
gst_base_src_set_do_timestamp (src, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -1540,7 +1598,7 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_BLOCKSIZE:
|
||||
g_value_set_ulong (value, src->blocksize);
|
||||
g_value_set_ulong (value, gst_base_src_get_blocksize (src));
|
||||
break;
|
||||
case PROP_NUM_BUFFERS:
|
||||
g_value_set_int (value, src->num_buffers);
|
||||
|
@ -1549,7 +1607,7 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
g_value_set_boolean (value, src->data.ABI.typefind);
|
||||
break;
|
||||
case PROP_DO_TIMESTAMP:
|
||||
g_value_set_boolean (value, src->priv->do_timestamp);
|
||||
g_value_set_boolean (value, gst_base_src_get_do_timestamp (src));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
|
@ -241,8 +241,10 @@ gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live,
|
|||
GstClockTime * min_latency,
|
||||
GstClockTime * max_latency);
|
||||
|
||||
void gst_base_src_set_do_timestamp (GstBaseSrc *src,
|
||||
gboolean timestamp);
|
||||
void gst_base_src_set_blocksize (GstBaseSrc *src, gulong blocksize);
|
||||
gulong gst_base_src_get_blocksize (GstBaseSrc *src);
|
||||
|
||||
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
|
||||
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
Loading…
Reference in a new issue