mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-19 20:46:22 +00:00
Correctly distribute clock/scheduler to elements
Original commit message from CVS: * gst/elements/gstfakesink.c: (gst_fakesink_event): * gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions), (gst_fakesrc_loop), (gst_fakesrc_activate): * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop): * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstcaps.c: (gst_caps_intersect): * gst/gstelement.c: (gst_element_pads_activate), (gst_element_change_state), (gst_element_create_task): * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_set_loop_function), (gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function), (gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function), (gst_pad_unlink), (gst_pad_link_prepare_filtered), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink), (gst_pad_configure_src), (gst_pad_realize), (gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps), (gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push), (gst_pad_push_event): * gst/gstpad.h: * gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose), (is_eos), (pipeline_bus_handler), (gst_pipeline_change_state), (gst_pipeline_get_scheduler), (gst_pipeline_get_bus): * gst/gstpipeline.h: * gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_src_activate), (gst_queue_change_state): * gst/gsttask.h: * gst/gstutils.c: (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_can_link_filtered): * gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func): * libs/gst/Makefile.am: * tools/gst-inspect.c: (print_pad_info): * tools/gst-launch.c: (main): * tools/gst-xmlinspect.c: (print_element_info): Correctly distribute clock/scheduler to elements Caps intersection improvement. MT fixes. Work on scheduling simplifications, get rid of _pull and prepare for scheduling setup. More work on capsnego.
This commit is contained in:
parent
ccb77fc69f
commit
457e99ab07
24 changed files with 850 additions and 462 deletions
55
ChangeLog
55
ChangeLog
|
@ -1,3 +1,58 @@
|
||||||
|
2004-12-20 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/elements/gstfakesink.c: (gst_fakesink_event):
|
||||||
|
* gst/elements/gstfakesrc.c: (gst_fakesrc_update_functions),
|
||||||
|
(gst_fakesrc_loop), (gst_fakesrc_activate):
|
||||||
|
* gst/elements/gstfilesrc.c: (gst_filesrc_init),
|
||||||
|
(gst_filesrc_getrange), (gst_filesrc_get), (gst_filesrc_loop):
|
||||||
|
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index),
|
||||||
|
(gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler),
|
||||||
|
(gst_bin_add_func), (gst_bin_iterate_elements),
|
||||||
|
(gst_bin_change_state), (gst_bin_get_by_name_recurse_up):
|
||||||
|
* gst/gstcaps.c: (gst_caps_intersect):
|
||||||
|
* gst/gstelement.c: (gst_element_pads_activate),
|
||||||
|
(gst_element_change_state), (gst_element_create_task):
|
||||||
|
* gst/gstobject.c: (gst_object_class_init), (gst_object_ref),
|
||||||
|
(gst_object_unref), (gst_object_sink), (gst_object_dispose),
|
||||||
|
(gst_object_dispatch_properties_changed), (gst_object_set_name),
|
||||||
|
(gst_object_set_parent), (gst_object_unparent),
|
||||||
|
(gst_object_check_uniqueness), (gst_object_get_path_string):
|
||||||
|
* gst/gstpad.c: (gst_real_pad_init), (gst_real_pad_get_property),
|
||||||
|
(gst_pad_set_active), (gst_pad_is_active),
|
||||||
|
(gst_pad_set_blocked_async), (gst_pad_set_loop_function),
|
||||||
|
(gst_pad_set_getrange_function), (gst_pad_set_acceptcaps_function),
|
||||||
|
(gst_pad_set_fixatecaps_function), (gst_pad_set_setcaps_function),
|
||||||
|
(gst_pad_unlink), (gst_pad_link_prepare_filtered),
|
||||||
|
(gst_pad_link_filtered), (gst_pad_relink_filtered),
|
||||||
|
(gst_pad_get_caps), (gst_pad_set_caps), (gst_pad_configure_sink),
|
||||||
|
(gst_pad_configure_src), (gst_pad_realize),
|
||||||
|
(gst_pad_get_allowed_caps), (gst_pad_get_negotiated_caps),
|
||||||
|
(gst_pad_get_filter_caps), (gst_pad_alloc_buffer), (gst_pad_push),
|
||||||
|
(gst_pad_push_event):
|
||||||
|
* gst/gstpad.h:
|
||||||
|
* gst/gstpipeline.c: (gst_pipeline_init), (gst_pipeline_dispose),
|
||||||
|
(is_eos), (pipeline_bus_handler), (gst_pipeline_change_state),
|
||||||
|
(gst_pipeline_get_scheduler), (gst_pipeline_get_bus):
|
||||||
|
* gst/gstpipeline.h:
|
||||||
|
* gst/gstqueue.c: (gst_queue_init), (gst_queue_locked_flush),
|
||||||
|
(gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop),
|
||||||
|
(gst_queue_src_activate), (gst_queue_change_state):
|
||||||
|
* gst/gsttask.h:
|
||||||
|
* gst/gstutils.c: (gst_element_get_compatible_pad_filtered),
|
||||||
|
(gst_element_link_pads_filtered), (gst_element_unlink),
|
||||||
|
(gst_pad_can_link_filtered):
|
||||||
|
* gst/schedulers/threadscheduler.c: (gst_thread_scheduler_func):
|
||||||
|
* libs/gst/Makefile.am:
|
||||||
|
* tools/gst-inspect.c: (print_pad_info):
|
||||||
|
* tools/gst-launch.c: (main):
|
||||||
|
* tools/gst-xmlinspect.c: (print_element_info):
|
||||||
|
Correctly distribute clock/scheduler to elements
|
||||||
|
Caps intersection improvement.
|
||||||
|
MT fixes.
|
||||||
|
Work on scheduling simplifications, get rid of _pull and prepare
|
||||||
|
for scheduling setup.
|
||||||
|
More work on capsnego.
|
||||||
|
|
||||||
2004-12-14 Thomas Vander Stichele <thomas at apestaart dot org>
|
2004-12-14 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* check/gst/gstobject.c:
|
* check/gst/gstobject.c:
|
||||||
|
|
|
@ -332,7 +332,7 @@ gst_fakesink_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
gst_element_finish_preroll (GST_ELEMENT (fakesink),
|
gst_element_finish_preroll (GST_ELEMENT (fakesink),
|
||||||
GST_STREAM_GET_LOCK (pad));
|
GST_STREAM_GET_LOCK (pad));
|
||||||
gst_pipeline_post_message (GST_ELEMENT_MANAGER (fakesink),
|
gst_element_post_message (GST_ELEMENT (fakesink),
|
||||||
gst_message_new_eos (GST_OBJECT (fakesink)));
|
gst_message_new_eos (GST_OBJECT (fakesink)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,7 @@ 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 GstFlowReturn gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer);
|
static gboolean gst_fakesrc_loop (GstPad * pad);
|
||||||
static void gst_fakesrc_loop (GstElement * element);
|
|
||||||
|
|
||||||
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
@ -471,13 +470,8 @@ gst_fakesrc_update_functions (GstFakeSrc * src)
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
|
||||||
if (src->loop_based) {
|
|
||||||
gst_pad_set_get_function (pad, NULL);
|
|
||||||
} else {
|
|
||||||
gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
||||||
|
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
||||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
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_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||||
|
@ -784,20 +778,16 @@ gst_fakesrc_create_buffer (GstFakeSrc * src)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static gboolean
|
||||||
gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
gboolean result = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
|
|
||||||
|
|
||||||
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_FAKESRC (src), GST_FLOW_ERROR);
|
|
||||||
|
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
if (src->need_flush) {
|
if (src->need_flush) {
|
||||||
src->need_flush = FALSE;
|
src->need_flush = FALSE;
|
||||||
|
@ -809,14 +799,14 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
if (src->rt_num_buffers > 0)
|
if (src->rt_num_buffers > 0)
|
||||||
|
@ -826,7 +816,7 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +856,7 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
|
|
||||||
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
*buffer = buf;
|
gst_pad_push (pad, buf);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
@ -874,26 +864,24 @@ done:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* gst_fakesrc_loop:
|
* gst_fakesrc_loop:
|
||||||
* @element: the faksesrc to loop
|
* @element: the faksesrc to loop
|
||||||
*
|
*
|
||||||
* generate an empty buffer and push it to the next element.
|
* generate an empty buffer and push it to the next element.
|
||||||
*/
|
*/
|
||||||
static void
|
static gboolean
|
||||||
gst_fakesrc_loop (GstElement * element)
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
const GList *pads;
|
const GList *pads;
|
||||||
GstTask *task;
|
GstTask *task;
|
||||||
|
|
||||||
g_return_if_fail (element != NULL);
|
src = GST_FAKESRC (GST_PAD_PARENT (pad));
|
||||||
g_return_if_fail (GST_IS_FAKESRC (element));
|
|
||||||
|
|
||||||
src = GST_FAKESRC (element);
|
|
||||||
task = src->task;
|
task = src->task;
|
||||||
|
|
||||||
pads = element->pads;
|
pads = GST_ELEMENT (src)->pads;
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
@ -902,22 +890,21 @@ gst_fakesrc_loop (GstElement * element)
|
||||||
|
|
||||||
ret = gst_fakesrc_get (pad, &buffer);
|
ret = gst_fakesrc_get (pad, &buffer);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ret = gst_pad_push (pad, buffer);
|
ret = gst_pad_push (pad, buffer);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->eos) {
|
if (src->eos) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pads = g_list_next (pads);
|
pads = g_list_next (pads);
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_fakesrc_activate (GstPad * pad, gboolean active)
|
gst_fakesrc_activate (GstPad * pad, gboolean active)
|
||||||
|
@ -929,11 +916,11 @@ gst_fakesrc_activate (GstPad * pad, gboolean active)
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
if (GST_ELEMENT_MANAGER (fakesrc)) {
|
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
fakesrc->task =
|
fakesrc->task =
|
||||||
gst_scheduler_create_task (GST_ELEMENT_MANAGER (fakesrc)->scheduler,
|
gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (fakesrc),
|
||||||
(GstTaskFunction) gst_fakesrc_loop, fakesrc);
|
(GstTaskFunction) gst_fakesrc_loop, pad);
|
||||||
|
|
||||||
gst_task_start (fakesrc->task);
|
gst_task_start (fakesrc->task);
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
|
@ -171,6 +171,8 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
static gboolean gst_filesrc_check_filesize (GstFileSrc * src);
|
static gboolean gst_filesrc_check_filesize (GstFileSrc * src);
|
||||||
static GstFlowReturn gst_filesrc_get (GstPad * pad, GstBuffer ** buffer);
|
static GstFlowReturn gst_filesrc_get (GstPad * pad, GstBuffer ** buffer);
|
||||||
|
static GstFlowReturn gst_filesrc_getrange (GstPad * pad, guint64 offset,
|
||||||
|
guint length, GstBuffer ** buffer);
|
||||||
static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event);
|
||||||
static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
||||||
GstFormat * format, gint64 * value);
|
GstFormat * format, gint64 * value);
|
||||||
|
@ -248,7 +250,7 @@ gst_filesrc_init (GstFileSrc * src)
|
||||||
src->srcpad =
|
src->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
||||||
"src");
|
"src");
|
||||||
gst_pad_set_get_function (src->srcpad, gst_filesrc_get);
|
gst_pad_set_getrange_function (src->srcpad, gst_filesrc_getrange);
|
||||||
gst_pad_set_activate_function (src->srcpad, gst_filesrc_activate);
|
gst_pad_set_activate_function (src->srcpad, gst_filesrc_activate);
|
||||||
gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event);
|
gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event);
|
||||||
gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask);
|
gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask);
|
||||||
|
@ -688,13 +690,27 @@ gst_filesrc_get_read (GstFileSrc * src)
|
||||||
return GST_DATA (buf);
|
return GST_DATA (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_filesrc_getrange (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** buffer)
|
||||||
|
{
|
||||||
|
GstFileSrc *src;
|
||||||
|
|
||||||
|
src = GST_FILESRC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
src->curoffset = offset;
|
||||||
|
src->block_size = length;
|
||||||
|
|
||||||
|
return gst_filesrc_get (pad, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_filesrc_get (GstPad * pad, GstBuffer ** buffer)
|
gst_filesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
{
|
{
|
||||||
GstFileSrc *src;
|
GstFileSrc *src;
|
||||||
GstData *data;
|
GstData *data;
|
||||||
|
|
||||||
src = GST_FILESRC (gst_pad_get_parent (pad));
|
src = GST_FILESRC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN),
|
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN),
|
||||||
GST_FLOW_WRONG_STATE);
|
GST_FLOW_WRONG_STATE);
|
||||||
|
@ -863,24 +879,25 @@ gst_filesrc_close_file (GstFileSrc * src)
|
||||||
GST_FLAG_UNSET (src, GST_FILESRC_OPEN);
|
GST_FLAG_UNSET (src, GST_FILESRC_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gst_filesrc_loop (GstElement * element)
|
gst_filesrc_loop (GstElement * element)
|
||||||
{
|
{
|
||||||
GstFileSrc *filesrc;
|
GstFileSrc *filesrc;
|
||||||
GstFlowReturn result;
|
gboolean result;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
filesrc = GST_FILESRC (element);
|
filesrc = GST_FILESRC (element);
|
||||||
|
|
||||||
result = gst_filesrc_get (filesrc->srcpad, &buffer);
|
result = gst_filesrc_get (filesrc->srcpad, &buffer);
|
||||||
if (result != GST_FLOW_OK) {
|
if (result != GST_FLOW_OK) {
|
||||||
gst_task_stop (filesrc->task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
result = gst_pad_push (filesrc->srcpad, buffer);
|
result = gst_pad_push (filesrc->srcpad, buffer);
|
||||||
if (result != GST_FLOW_OK) {
|
if (result != GST_FLOW_OK) {
|
||||||
gst_task_stop (filesrc->task);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
48
gst/gstbin.c
48
gst/gstbin.c
|
@ -61,6 +61,8 @@ static void gst_bin_set_index (GstElement * element, GstIndex * index);
|
||||||
#endif
|
#endif
|
||||||
static void gst_bin_set_clock (GstElement * element, GstClock * clock);
|
static void gst_bin_set_clock (GstElement * element, GstClock * clock);
|
||||||
static GstClock *gst_bin_get_clock (GstElement * element);
|
static GstClock *gst_bin_get_clock (GstElement * element);
|
||||||
|
static void gst_bin_set_bus (GstElement * element, GstBus * bus);
|
||||||
|
static void gst_bin_set_scheduler (GstElement * element, GstScheduler * sched);
|
||||||
|
|
||||||
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
|
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
|
||||||
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
|
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
|
||||||
|
@ -167,6 +169,8 @@ gst_bin_class_init (GstBinClass * klass)
|
||||||
#endif
|
#endif
|
||||||
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock);
|
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock);
|
||||||
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock);
|
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock);
|
||||||
|
gstelement_class->set_bus = GST_DEBUG_FUNCPTR (gst_bin_set_bus);
|
||||||
|
gstelement_class->set_scheduler = GST_DEBUG_FUNCPTR (gst_bin_set_scheduler);
|
||||||
|
|
||||||
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
|
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
|
||||||
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
|
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
|
||||||
|
@ -252,10 +256,47 @@ gst_bin_get_clock (GstElement * element)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bin_set_bus (GstElement * element, GstBus * bus)
|
||||||
|
{
|
||||||
|
GList *children;
|
||||||
|
GstBin *bin;
|
||||||
|
|
||||||
|
bin = GST_BIN (element);
|
||||||
|
|
||||||
|
parent_class->set_bus (element, bus);
|
||||||
|
|
||||||
|
GST_LOCK (bin);
|
||||||
|
for (children = bin->children; children; children = g_list_next (children)) {
|
||||||
|
GstElement *child = GST_ELEMENT (children->data);
|
||||||
|
|
||||||
|
gst_element_set_bus (child, bus);
|
||||||
|
}
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bin_set_scheduler (GstElement * element, GstScheduler * sched)
|
||||||
|
{
|
||||||
|
GList *children;
|
||||||
|
GstBin *bin;
|
||||||
|
|
||||||
|
bin = GST_BIN (element);
|
||||||
|
|
||||||
|
parent_class->set_scheduler (element, sched);
|
||||||
|
|
||||||
|
GST_LOCK (bin);
|
||||||
|
for (children = bin->children; children; children = g_list_next (children)) {
|
||||||
|
GstElement *child = GST_ELEMENT (children->data);
|
||||||
|
|
||||||
|
gst_element_set_scheduler (child, sched);
|
||||||
|
}
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_bin_add_func (GstBin * bin, GstElement * element)
|
gst_bin_add_func (GstBin * bin, GstElement * element)
|
||||||
{
|
{
|
||||||
GstPipeline *manager;
|
|
||||||
gchar *elem_name;
|
gchar *elem_name;
|
||||||
|
|
||||||
/* we obviously can't add ourself to ourself */
|
/* we obviously can't add ourself to ourself */
|
||||||
|
@ -283,8 +324,9 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
|
||||||
bin->numchildren++;
|
bin->numchildren++;
|
||||||
bin->children_cookie++;
|
bin->children_cookie++;
|
||||||
|
|
||||||
manager = GST_ELEMENT (bin)->manager;
|
gst_element_set_manager (element, GST_ELEMENT (bin)->manager);
|
||||||
gst_element_set_manager (element, manager);
|
gst_element_set_bus (element, GST_ELEMENT (bin)->bus);
|
||||||
|
gst_element_set_scheduler (element, GST_ELEMENT (bin)->scheduler);
|
||||||
|
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
|
|
@ -872,10 +872,11 @@ gst_caps_structure_union (const GstStructure * struct1,
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
|
gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j, k;
|
||||||
GstStructure *struct1;
|
GstStructure *struct1;
|
||||||
GstStructure *struct2;
|
GstStructure *struct2;
|
||||||
GstCaps *dest;
|
GstCaps *dest;
|
||||||
|
GstStructure *istruct;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
|
g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
|
||||||
g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
|
g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
|
||||||
|
@ -889,38 +890,42 @@ gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
|
||||||
return gst_caps_copy (caps1);
|
return gst_caps_copy (caps1);
|
||||||
|
|
||||||
dest = gst_caps_new_empty ();
|
dest = gst_caps_new_empty ();
|
||||||
/* run zigzag on top line first
|
|
||||||
*
|
/* run zigzag on top line then right line, this preserves the caps order
|
||||||
* 1 2 4 ..
|
* much better than a simple loop.
|
||||||
* 3 5 ..
|
*
|
||||||
* 6 ..
|
* This algorithm zigzags over the caps structures as demonstrated in
|
||||||
* ..
|
* the folowing matrix:
|
||||||
*
|
*
|
||||||
|
* caps1
|
||||||
|
* +-------------
|
||||||
|
* | 1 2 4 7
|
||||||
|
* caps2 | 3 5 8 10
|
||||||
|
* | 6 9 11 12
|
||||||
|
*
|
||||||
|
* First we iterate over the caps1 structures (top line) intersecting
|
||||||
|
* the structures diagonally down, then we iterate over the caps2
|
||||||
|
* structures.
|
||||||
*/
|
*/
|
||||||
#if 0
|
for (i = 0; i < caps1->structs->len + caps2->structs->len - 1; i++) {
|
||||||
for (i = 0; i < caps1->structs->len; i++) {
|
/* caps1 index goes from 0 to caps1->structs->len-1 */
|
||||||
struct1 = gst_caps_get_structure (caps1, i);
|
j = MIN (i, caps1->structs->len - 1);
|
||||||
for (j = 0; j < caps2->structs->len; j++) {
|
/* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
|
||||||
}
|
* up from 1 to caps2->structs->len - 1 */
|
||||||
}
|
k = MAX (0, i - j);
|
||||||
#endif
|
|
||||||
/* run zigzag on right line
|
|
||||||
*
|
|
||||||
* .. 1
|
|
||||||
* .. 2 4
|
|
||||||
* .. 3 5 6
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* FIXME use loop that preserves the order better */
|
/* now run the diagonal line, end condition is the left or bottom
|
||||||
for (i = 0; i < caps1->structs->len; i++) {
|
* border */
|
||||||
struct1 = gst_caps_get_structure (caps1, i);
|
while (k < caps2->structs->len && j >= 0) {
|
||||||
for (j = 0; j < caps2->structs->len; j++) {
|
struct1 = gst_caps_get_structure (caps1, j);
|
||||||
GstStructure *istruct;
|
struct2 = gst_caps_get_structure (caps2, k);
|
||||||
|
|
||||||
struct2 = gst_caps_get_structure (caps2, j);
|
|
||||||
istruct = gst_caps_structure_intersect (struct1, struct2);
|
istruct = gst_caps_structure_intersect (struct1, struct2);
|
||||||
|
|
||||||
gst_caps_append_structure (dest, istruct);
|
gst_caps_append_structure (dest, istruct);
|
||||||
|
/* move down left */
|
||||||
|
k++;
|
||||||
|
j--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1797,30 +1797,41 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is called with STATE_LOCK */
|
/* is called with STATE_LOCK */
|
||||||
/* FIXME make MT safe */
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_element_pads_activate (GstElement * element, gboolean active)
|
gst_element_pads_activate (GstElement * element, gboolean active)
|
||||||
{
|
{
|
||||||
GList *pads;
|
GList *pads;
|
||||||
gboolean result = TRUE;
|
gboolean result;
|
||||||
|
guint32 cookie;
|
||||||
|
|
||||||
|
GST_LOCK (element);
|
||||||
|
restart:
|
||||||
|
result = TRUE;
|
||||||
pads = element->pads;
|
pads = element->pads;
|
||||||
while (pads && result) {
|
cookie = element->pads_cookie;
|
||||||
|
for (; pads && result; pads = g_list_next (pads)) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
|
||||||
pads = g_list_next (pads);
|
gst_object_ref (GST_OBJECT (pad));
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
|
||||||
if (!GST_IS_REAL_PAD (pad))
|
if (GST_IS_REAL_PAD (pad)) {
|
||||||
continue;
|
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||||
|
"%sactivating pad %s", (active ? "" : "(de)"), GST_OBJECT_NAME (pad));
|
||||||
|
result &= gst_pad_set_active (pad, active);
|
||||||
|
}
|
||||||
|
gst_object_unref (GST_OBJECT (pad));
|
||||||
|
|
||||||
result &= gst_pad_set_active (pad, active);
|
GST_LOCK (element);
|
||||||
|
if (cookie != element->pads_cookie)
|
||||||
|
goto restart;
|
||||||
}
|
}
|
||||||
|
GST_UNLOCK (element);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is called with STATE_LOCK */
|
/* is called with STATE_LOCK */
|
||||||
/* FIXME make MT safe */
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
gst_element_change_state (GstElement * element)
|
gst_element_change_state (GstElement * element)
|
||||||
{
|
{
|
||||||
|
@ -1857,10 +1868,12 @@ gst_element_change_state (GstElement * element)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_PLAYING:
|
case GST_STATE_PAUSED_TO_PLAYING:
|
||||||
|
GST_LOCK (element);
|
||||||
if (GST_ELEMENT_MANAGER (element)) {
|
if (GST_ELEMENT_MANAGER (element)) {
|
||||||
element->base_time =
|
element->base_time =
|
||||||
GST_ELEMENT (GST_ELEMENT_MANAGER (element))->base_time;
|
GST_ELEMENT (GST_ELEMENT_MANAGER (element))->base_time;
|
||||||
}
|
}
|
||||||
|
GST_UNLOCK (element);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PLAYING_TO_PAUSED:
|
case GST_STATE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
|
@ -2264,16 +2277,16 @@ GstTask *
|
||||||
gst_element_create_task (GstElement * element, GstTaskFunction func,
|
gst_element_create_task (GstElement * element, GstTaskFunction func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GstPipeline *pipeline;
|
GstScheduler *sched;
|
||||||
GstTask *result = NULL;
|
GstTask *result = NULL;
|
||||||
|
|
||||||
GST_LOCK (element);
|
GST_LOCK (element);
|
||||||
pipeline = GST_ELEMENT_MANAGER (element);
|
sched = GST_ELEMENT_SCHEDULER (element);
|
||||||
gst_object_ref (GST_OBJECT (pipeline));
|
gst_object_ref (GST_OBJECT (sched));
|
||||||
GST_UNLOCK (element);
|
GST_UNLOCK (element);
|
||||||
if (pipeline) {
|
if (sched) {
|
||||||
result = gst_scheduler_create_task (pipeline->scheduler, func, data);
|
result = gst_scheduler_create_task (sched, func, data);
|
||||||
gst_object_unref (GST_OBJECT (pipeline));
|
gst_object_unref (GST_OBJECT (sched));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -314,6 +314,7 @@ gst_object_unref (GstObject * object)
|
||||||
PATCH_REFCOUNT (object);
|
PATCH_REFCOUNT (object);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
/* FIXME, not MT safe because glib is not MT safe */
|
||||||
g_object_unref (object);
|
g_object_unref (object);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
607
gst/gstpad.c
607
gst/gstpad.c
|
@ -234,7 +234,6 @@ gst_real_pad_init (GstRealPad * pad)
|
||||||
pad->peer = NULL;
|
pad->peer = NULL;
|
||||||
|
|
||||||
pad->chainfunc = NULL;
|
pad->chainfunc = NULL;
|
||||||
pad->getfunc = NULL;
|
|
||||||
|
|
||||||
pad->ghostpads = NULL;
|
pad->ghostpads = NULL;
|
||||||
pad->caps = NULL;
|
pad->caps = NULL;
|
||||||
|
@ -251,8 +250,7 @@ gst_real_pad_init (GstRealPad * pad)
|
||||||
pad->formatsfunc = gst_pad_get_formats_default;
|
pad->formatsfunc = gst_pad_get_formats_default;
|
||||||
pad->querytypefunc = gst_pad_get_query_types_default;
|
pad->querytypefunc = gst_pad_get_query_types_default;
|
||||||
|
|
||||||
GST_FLAG_SET (pad, GST_PAD_DISABLED);
|
GST_FLAG_UNSET (pad, GST_PAD_ACTIVE);
|
||||||
GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
|
|
||||||
|
|
||||||
pad->stream_lock = g_mutex_new ();
|
pad->stream_lock = g_mutex_new ();
|
||||||
pad->stream_cond = g_cond_new ();
|
pad->stream_cond = g_cond_new ();
|
||||||
|
@ -286,7 +284,7 @@ gst_real_pad_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case REAL_ARG_ACTIVE:
|
case REAL_ARG_ACTIVE:
|
||||||
g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
|
g_value_set_boolean (value, GST_FLAG_IS_SET (object, GST_PAD_ACTIVE));
|
||||||
break;
|
break;
|
||||||
case REAL_ARG_CAPS:
|
case REAL_ARG_CAPS:
|
||||||
g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
|
g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
|
||||||
|
@ -450,7 +448,7 @@ gst_pad_set_active (GstPad * pad, gboolean active)
|
||||||
if (!active) {
|
if (!active) {
|
||||||
GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
|
GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (realpad));
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
GST_FLAG_SET (realpad, GST_PAD_DISABLED);
|
GST_FLAG_UNSET (realpad, GST_PAD_ACTIVE);
|
||||||
/* unlock blocked pads so element can resume and stop */
|
/* unlock blocked pads so element can resume and stop */
|
||||||
GST_PAD_BLOCK_SIGNAL (realpad);
|
GST_PAD_BLOCK_SIGNAL (realpad);
|
||||||
}
|
}
|
||||||
|
@ -470,7 +468,7 @@ gst_pad_set_active (GstPad * pad, gboolean active)
|
||||||
if (active && result == TRUE) {
|
if (active && result == TRUE) {
|
||||||
GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s",
|
GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (realpad));
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
GST_FLAG_UNSET (realpad, GST_PAD_DISABLED);
|
GST_FLAG_SET (realpad, GST_PAD_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -503,7 +501,7 @@ gst_pad_is_active (GstPad * pad)
|
||||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||||
|
|
||||||
GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
|
GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
|
||||||
result = !GST_FLAG_IS_SET (realpad, GST_PAD_DISABLED);
|
result = !!GST_FLAG_IS_SET (realpad, GST_PAD_ACTIVE);
|
||||||
GST_UNLOCK (realpad);
|
GST_UNLOCK (realpad);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -671,6 +669,24 @@ gst_pad_set_activate_function (GstPad * pad, GstPadActivateFunction activate)
|
||||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (activate));
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (activate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pad_set_loop_function:
|
||||||
|
* @pad: a real sink #GstPad.
|
||||||
|
* @chain: the #GstPadLoopFunction to set.
|
||||||
|
*
|
||||||
|
* Sets the given loop function for the pad. The loop function is called
|
||||||
|
* repeadedly to pull/push buffers from/to the peer pad.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_pad_set_loop_function (GstPad * pad, GstPadLoopFunction loop)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
|
|
||||||
|
GST_RPAD_LOOPFUNC (pad) = loop;
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PADS, "loopfunc for %s:%s set to %s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (loop));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_set_chain_function:
|
* gst_pad_set_chain_function:
|
||||||
* @pad: a real sink #GstPad.
|
* @pad: a real sink #GstPad.
|
||||||
|
@ -691,23 +707,23 @@ gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_set_get_function:
|
* gst_pad_set_getrange_function:
|
||||||
* @pad: a real source #GstPad.
|
* @pad: a real source #GstPad.
|
||||||
* @get: the #GstPadGetFunction to set.
|
* @get: the #GstPadGetRangeFunction to set.
|
||||||
*
|
*
|
||||||
* Sets the given get function for the pad. The get function is called to
|
* Sets the given getrange function for the pad. The getrange function is called to
|
||||||
* produce a new #GstData to start the processing pipeline. Get functions cannot
|
* produce a new #GstBuffer to start the processing pipeline. Getrange functions cannot
|
||||||
* return %NULL.
|
* return %NULL.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_pad_set_get_function (GstPad * pad, GstPadGetFunction get)
|
gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
|
g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
|
||||||
|
|
||||||
GST_RPAD_GETFUNC (pad) = get;
|
GST_RPAD_GETRANGEFUNC (pad) = get;
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PADS, "getfunc for %s:%s set to %s",
|
GST_CAT_DEBUG (GST_CAT_PADS, "getrangefunc for %s:%s set to %s",
|
||||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +1023,8 @@ gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
|
||||||
* but this is discouraged.
|
* but this is discouraged.
|
||||||
*
|
*
|
||||||
* You do not need to call this function if @pad's allowed caps are always the
|
* You do not need to call this function if @pad's allowed caps are always the
|
||||||
* same as the pad template caps.
|
* same as the pad template caps. This can only be true if the padtemplate
|
||||||
|
* has fixed simple caps.
|
||||||
*
|
*
|
||||||
* For most filters, the caps returned by @getcaps is directly affected by the
|
* For most filters, the caps returned by @getcaps is directly affected by the
|
||||||
* allowed caps on other pads. For demuxers and decoders, the caps returned by
|
* allowed caps on other pads. For demuxers and decoders, the caps returned by
|
||||||
|
@ -1015,7 +1032,8 @@ gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
|
||||||
* @getcaps should return the most specific caps it reasonably can, since this
|
* @getcaps should return the most specific caps it reasonably can, since this
|
||||||
* helps with autoplugging.
|
* helps with autoplugging.
|
||||||
*
|
*
|
||||||
* Note that the return value from @getcaps is owned by the caller.
|
* Note that the return value from @getcaps is owned by the caller, so the caller
|
||||||
|
* should unref the caps after usage.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
|
gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
|
||||||
|
@ -1027,6 +1045,38 @@ gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
|
||||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_pad_set_acceptcaps_function (GstPad * pad,
|
||||||
|
GstPadAcceptCapsFunction acceptcaps)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
|
|
||||||
|
GST_RPAD_ACCEPTCAPSFUNC (pad) = acceptcaps;
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PADS, "acceptcapsfunc for %s:%s set to %s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (acceptcaps));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_pad_set_fixatecaps_function (GstPad * pad,
|
||||||
|
GstPadFixateCapsFunction fixatecaps)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
|
|
||||||
|
GST_RPAD_FIXATECAPSFUNC (pad) = fixatecaps;
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PADS, "fixatecapsfunc for %s:%s set to %s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (fixatecaps));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_pad_set_setcaps_function (GstPad * pad, GstPadSetCapsFunction setcaps)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_REAL_PAD (pad));
|
||||||
|
|
||||||
|
GST_RPAD_SETCAPSFUNC (pad) = setcaps;
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PADS, "setcapsfunc for %s:%s set to %s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (setcaps));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_set_bufferalloc_function:
|
* gst_pad_set_bufferalloc_function:
|
||||||
* @pad: a real sink #GstPad.
|
* @pad: a real sink #GstPad.
|
||||||
|
@ -1176,6 +1226,7 @@ lost_ghostpad:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME leftover from an attempt at refactoring... */
|
||||||
static GstPadLinkReturn
|
static GstPadLinkReturn
|
||||||
gst_pad_link_prepare_filtered (GstPad * srcpad, GstPad * sinkpad,
|
gst_pad_link_prepare_filtered (GstPad * srcpad, GstPad * sinkpad,
|
||||||
GstRealPad ** outrealsrc, GstRealPad ** outrealsink,
|
GstRealPad ** outrealsrc, GstRealPad ** outrealsink,
|
||||||
|
@ -1245,6 +1296,8 @@ not_srcpad:
|
||||||
}
|
}
|
||||||
src_was_linked:
|
src_was_linked:
|
||||||
{
|
{
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was linked",
|
||||||
|
GST_DEBUG_PAD_NAME (realsrc));
|
||||||
/* we do not emit a warning in this case because unlinking cannot
|
/* we do not emit a warning in this case because unlinking cannot
|
||||||
* be made MT safe.*/
|
* be made MT safe.*/
|
||||||
GST_UNLOCK (realsrc);
|
GST_UNLOCK (realsrc);
|
||||||
|
@ -1265,6 +1318,8 @@ not_sinkpad:
|
||||||
}
|
}
|
||||||
sink_was_linked:
|
sink_was_linked:
|
||||||
{
|
{
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was linked",
|
||||||
|
GST_DEBUG_PAD_NAME (realsink));
|
||||||
/* we do not emit a warning in this case because unlinking cannot
|
/* we do not emit a warning in this case because unlinking cannot
|
||||||
* be made MT safe.*/
|
* be made MT safe.*/
|
||||||
GST_UNLOCK (realsink);
|
GST_UNLOCK (realsink);
|
||||||
|
@ -1493,24 +1548,92 @@ gst_pad_relink_filtered (GstPad * srcpad, GstPad * sinkpad,
|
||||||
const GstCaps * filtercaps)
|
const GstCaps * filtercaps)
|
||||||
{
|
{
|
||||||
GstRealPad *realsrc, *realsink;
|
GstRealPad *realsrc, *realsink;
|
||||||
GstPadLinkReturn result;
|
|
||||||
|
|
||||||
result = gst_pad_link_prepare_filtered (srcpad, sinkpad, &realsrc, &realsink,
|
/* FIXME refactor and share code with link/unlink */
|
||||||
filtercaps);
|
|
||||||
|
|
||||||
if (result != GST_PAD_LINK_OK)
|
/* generic checks */
|
||||||
goto prepare_failed;
|
g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
|
||||||
|
g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
|
||||||
|
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "trying to relink %s:%s and %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
|
||||||
|
|
||||||
|
/* now we need to deal with the real/ghost stuff */
|
||||||
|
GST_PAD_REALIZE_AND_LOCK (srcpad, realsrc, lost_src_ghostpad);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC))
|
||||||
|
goto not_srcpad;
|
||||||
|
|
||||||
|
GST_PAD_REALIZE_AND_LOCK (sinkpad, realsink, lost_sink_ghostpad);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK))
|
||||||
|
goto not_sinkpad;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (GST_RPAD_PEER (realsink) != realsrc))
|
||||||
|
goto not_linked_together;
|
||||||
|
|
||||||
|
if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "*actually* relinking %s:%s and %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update filter */
|
||||||
|
if (filtercaps) {
|
||||||
|
GstCaps *filtercopy;
|
||||||
|
|
||||||
|
filtercopy = gst_caps_copy (filtercaps);
|
||||||
|
filtercopy = gst_caps_ref (filtercopy);
|
||||||
|
|
||||||
|
gst_caps_replace (&GST_PAD_APPFILTER (realsrc), filtercopy);
|
||||||
|
gst_caps_replace (&GST_PAD_APPFILTER (realsink), filtercopy);
|
||||||
|
} else {
|
||||||
|
gst_caps_replace (&GST_PAD_APPFILTER (realsrc), NULL);
|
||||||
|
gst_caps_replace (&GST_PAD_APPFILTER (realsink), NULL);
|
||||||
|
}
|
||||||
/* clear caps to force renegotiation */
|
/* clear caps to force renegotiation */
|
||||||
gst_caps_replace (&GST_PAD_CAPS (realsrc), NULL);
|
gst_caps_replace (&GST_PAD_CAPS (realsrc), NULL);
|
||||||
gst_caps_replace (&GST_PAD_CAPS (realsink), NULL);
|
gst_caps_replace (&GST_PAD_CAPS (realsink), NULL);
|
||||||
GST_UNLOCK (realsink);
|
GST_UNLOCK (realsink);
|
||||||
GST_UNLOCK (realsrc);
|
GST_UNLOCK (realsrc);
|
||||||
|
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "relinked %s:%s and %s:%s, successful",
|
||||||
|
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
|
||||||
|
|
||||||
return GST_PAD_LINK_OK;
|
return GST_PAD_LINK_OK;
|
||||||
|
|
||||||
prepare_failed:
|
lost_src_ghostpad:
|
||||||
return result;
|
{
|
||||||
|
return GST_PAD_LINK_REFUSED;
|
||||||
|
}
|
||||||
|
not_srcpad:
|
||||||
|
{
|
||||||
|
g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc));
|
||||||
|
GST_UNLOCK (realsrc);
|
||||||
|
return GST_PAD_LINK_WRONG_DIRECTION;
|
||||||
|
}
|
||||||
|
lost_sink_ghostpad:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("lost sink ghostpad");
|
||||||
|
GST_UNLOCK (realsrc);
|
||||||
|
return GST_PAD_LINK_REFUSED;
|
||||||
|
}
|
||||||
|
not_sinkpad:
|
||||||
|
{
|
||||||
|
g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink));
|
||||||
|
GST_UNLOCK (realsink);
|
||||||
|
GST_UNLOCK (realsrc);
|
||||||
|
return GST_PAD_LINK_WRONG_DIRECTION;
|
||||||
|
}
|
||||||
|
not_linked_together:
|
||||||
|
{
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was not linked with sink %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
|
||||||
|
/* we do not emit a warning in this case because unlinking cannot
|
||||||
|
* be made MT safe.*/
|
||||||
|
GST_UNLOCK (realsink);
|
||||||
|
GST_UNLOCK (realsrc);
|
||||||
|
return GST_PAD_LINK_REFUSED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1535,7 +1658,7 @@ gst_pad_get_caps (GstPad * pad)
|
||||||
GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
|
GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
|
||||||
GST_DEBUG_PAD_NAME (realpad), realpad);
|
GST_DEBUG_PAD_NAME (realpad), realpad);
|
||||||
|
|
||||||
if (GST_PAD_IS_DISPATCHING (realpad)) {
|
if (GST_RPAD_IS_IN_GETCAPS (realpad)) {
|
||||||
GST_CAT_DEBUG (GST_CAT_CAPS,
|
GST_CAT_DEBUG (GST_CAT_CAPS,
|
||||||
"pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
|
"pad %s:%s is already dispatching!", GST_DEBUG_PAD_NAME (realpad));
|
||||||
g_warning ("pad %s:%s recursively called getcaps!",
|
g_warning ("pad %s:%s recursively called getcaps!",
|
||||||
|
@ -1548,9 +1671,9 @@ gst_pad_get_caps (GstPad * pad)
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function");
|
GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function");
|
||||||
|
|
||||||
GST_FLAG_SET (realpad, GST_PAD_DISPATCHING);
|
GST_FLAG_SET (realpad, GST_PAD_IN_GETCAPS);
|
||||||
result = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad));
|
result = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad));
|
||||||
GST_FLAG_UNSET (realpad, GST_PAD_DISPATCHING);
|
GST_FLAG_UNSET (realpad, GST_PAD_IN_GETCAPS);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
g_critical ("pad %s:%s returned NULL caps from getcaps function\n",
|
g_critical ("pad %s:%s returned NULL caps from getcaps function\n",
|
||||||
|
@ -1629,9 +1752,27 @@ done:
|
||||||
gboolean
|
gboolean
|
||||||
gst_pad_set_caps (GstPad * pad, GstCaps * caps)
|
gst_pad_set_caps (GstPad * pad, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
GstPadSetCapsFunction setcaps;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
|
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
|
||||||
|
|
||||||
GST_LOCK (pad);
|
GST_LOCK (pad);
|
||||||
|
setcaps = GST_RPAD_SETCAPSFUNC (pad);
|
||||||
|
|
||||||
|
/* call setcaps function to configure the pad */
|
||||||
|
if (setcaps != NULL) {
|
||||||
|
if (!GST_RPAD_IS_IN_SETCAPS (pad)) {
|
||||||
|
GST_FLAG_SET (pad, GST_PAD_IN_SETCAPS);
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
if (!setcaps (pad, caps))
|
||||||
|
goto could_not_set;
|
||||||
|
GST_LOCK (pad);
|
||||||
|
} else {
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "pad %s:%s was dispatching",
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GST_PAD_CAPS (pad))
|
if (GST_PAD_CAPS (pad))
|
||||||
gst_caps_unref (GST_PAD_CAPS (pad));
|
gst_caps_unref (GST_PAD_CAPS (pad));
|
||||||
|
|
||||||
|
@ -1639,11 +1780,81 @@ gst_pad_set_caps (GstPad * pad, GstCaps * caps)
|
||||||
caps = gst_caps_ref (caps);
|
caps = gst_caps_ref (caps);
|
||||||
|
|
||||||
GST_PAD_CAPS (pad) = caps;
|
GST_PAD_CAPS (pad) = caps;
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "%s:%s caps %" GST_PTR_FORMAT,
|
||||||
|
GST_DEBUG_PAD_NAME (pad), caps);
|
||||||
GST_UNLOCK (pad);
|
GST_UNLOCK (pad);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (pad), "caps");
|
g_object_notify (G_OBJECT (pad), "caps");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
could_not_set:
|
||||||
|
{
|
||||||
|
GST_LOCK (pad);
|
||||||
|
GST_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " could not be set",
|
||||||
|
caps);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstPadAcceptCapsFunction acceptcaps;
|
||||||
|
GstPadSetCapsFunction setcaps;
|
||||||
|
|
||||||
|
acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
|
||||||
|
setcaps = GST_RPAD_SETCAPSFUNC (pad);
|
||||||
|
|
||||||
|
/* See if pad accepts the caps, by calling acceptcaps, only
|
||||||
|
* needed if no setcaps function */
|
||||||
|
if (setcaps == NULL && acceptcaps != NULL) {
|
||||||
|
if (!acceptcaps (pad, caps))
|
||||||
|
goto not_accepted;
|
||||||
|
}
|
||||||
|
/* set caps on pad if call succeeds */
|
||||||
|
gst_pad_set_caps (pad, caps);
|
||||||
|
/* no need to unref the caps here, set_caps takes a ref and
|
||||||
|
* our ref goes away when we leave this function. */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
not_accepted:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " not accepted", caps);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_pad_configure_src (GstPad * pad, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstPadAcceptCapsFunction acceptcaps;
|
||||||
|
GstPadSetCapsFunction setcaps;
|
||||||
|
|
||||||
|
acceptcaps = GST_RPAD_ACCEPTCAPSFUNC (pad);
|
||||||
|
setcaps = GST_RPAD_SETCAPSFUNC (pad);
|
||||||
|
|
||||||
|
/* See if pad accepts the caps, by calling acceptcaps, only
|
||||||
|
* needed if no setcaps function */
|
||||||
|
if (setcaps == NULL && acceptcaps != NULL) {
|
||||||
|
if (!acceptcaps (pad, caps))
|
||||||
|
goto not_accepted;
|
||||||
|
}
|
||||||
|
/* set caps on pad if call succeeds */
|
||||||
|
gst_pad_set_caps (pad, caps);
|
||||||
|
/* no need to unref the caps here, set_caps takes a ref and
|
||||||
|
* our ref goes away when we leave this function. */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
not_accepted:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "caps %" GST_PTR_FORMAT " not accepted", caps);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1747,45 +1958,47 @@ gst_pad_realize (GstPad * pad)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pad_get_allowed_caps:
|
* gst_pad_get_allowed_caps:
|
||||||
* @pad: a real #GstPad.
|
* @srcpad: a #GstPad, it must a a source pad.
|
||||||
*
|
*
|
||||||
* Gets the capabilities of the allowed media types that can flow through @pad.
|
* Gets the capabilities of the allowed media types that can flow through @pad
|
||||||
|
* and its peer. The pad must be a source pad.
|
||||||
* The caller must free the resulting caps.
|
* The caller must free the resulting caps.
|
||||||
*
|
*
|
||||||
* Returns: the allowed #GstCaps of the pad link. Free the caps when
|
* Returns: the allowed #GstCaps of the pad link. Free the caps when
|
||||||
* you no longer need it.
|
* you no longer need it. This function returns NULL when the @pad has no
|
||||||
|
* peer.
|
||||||
*
|
*
|
||||||
* MT safe.
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_pad_get_allowed_caps (GstPad * pad)
|
gst_pad_get_allowed_caps (GstPad * srcpad)
|
||||||
{
|
{
|
||||||
GstCaps *mycaps;
|
GstCaps *mycaps;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstCaps *peercaps;
|
GstCaps *peercaps;
|
||||||
GstRealPad *peer;
|
GstRealPad *realpad, *peer;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
|
g_return_val_if_fail (GST_IS_PAD (srcpad), NULL);
|
||||||
|
|
||||||
|
GST_PAD_REALIZE_AND_LOCK (srcpad, realpad, lost_ghostpad);
|
||||||
|
|
||||||
|
/* FIXME, allow sinkpads too? need to use the nexted locking
|
||||||
|
* with retry algorithm, see design docs */
|
||||||
|
if (G_UNLIKELY (!GST_PAD_IS_SRC (realpad)))
|
||||||
|
goto not_src;
|
||||||
|
|
||||||
|
if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
|
||||||
|
goto no_peer;
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting allowed caps",
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting allowed caps",
|
||||||
GST_DEBUG_PAD_NAME (pad));
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
|
||||||
mycaps = gst_pad_get_caps (pad);
|
gst_object_ref (GST_OBJECT_CAST (peer));
|
||||||
GST_LOCK (pad);
|
GST_UNLOCK (realpad);
|
||||||
peer = GST_RPAD_PEER (pad);
|
mycaps = gst_pad_get_caps (GST_PAD_CAST (realpad));
|
||||||
if (peer == NULL) {
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer, returning own caps",
|
|
||||||
GST_DEBUG_PAD_NAME (pad));
|
|
||||||
GST_UNLOCK (pad);
|
|
||||||
|
|
||||||
return mycaps;
|
|
||||||
} else {
|
|
||||||
gst_object_ref (GST_OBJECT (peer));
|
|
||||||
GST_UNLOCK (pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
peercaps = gst_pad_get_caps (GST_PAD_CAST (peer));
|
peercaps = gst_pad_get_caps (GST_PAD_CAST (peer));
|
||||||
gst_object_unref (GST_OBJECT (peer));
|
gst_object_unref (GST_OBJECT_CAST (peer));
|
||||||
|
|
||||||
caps = gst_caps_intersect (mycaps, peercaps);
|
caps = gst_caps_intersect (mycaps, peercaps);
|
||||||
gst_caps_unref (peercaps);
|
gst_caps_unref (peercaps);
|
||||||
|
@ -1794,6 +2007,137 @@ gst_pad_get_allowed_caps (GstPad * pad)
|
||||||
GST_CAT_DEBUG (GST_CAT_CAPS, "allowed caps %" GST_PTR_FORMAT, caps);
|
GST_CAT_DEBUG (GST_CAT_CAPS, "allowed caps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
|
lost_ghostpad:
|
||||||
|
{
|
||||||
|
GST_UNLOCK (srcpad);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
not_src:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: not a source pad",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
GST_UNLOCK (realpad);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
no_peer:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
GST_UNLOCK (realpad);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pad_get_negotiated_caps:
|
||||||
|
* @pad: a #GstPad.
|
||||||
|
*
|
||||||
|
* Gets the capabilities of the media type that currently flows through @pad
|
||||||
|
* and its peer.
|
||||||
|
*
|
||||||
|
* This function can be used on both src and sinkpads. Note that srcpads are
|
||||||
|
* always negotiated before sinkpads so it is possible that the negotiated caps
|
||||||
|
* on the srcpad do not match the negotiated caps of the peer.
|
||||||
|
*
|
||||||
|
* Returns: the negotiated #GstCaps of the pad link. Free the caps when
|
||||||
|
* you no longer need it. This function returns NULL when the @pad has no
|
||||||
|
* peer or is not negotiated yet.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*/
|
||||||
|
GstCaps *
|
||||||
|
gst_pad_get_negotiated_caps (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstRealPad *realpad, *peer;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||||
|
|
||||||
|
GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
|
||||||
|
|
||||||
|
if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
|
||||||
|
goto no_peer;
|
||||||
|
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting negotiated caps",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
|
||||||
|
caps = GST_RPAD_CAPS (realpad);
|
||||||
|
if (caps)
|
||||||
|
gst_caps_ref (caps);
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "negotiated caps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
lost_ghostpad:
|
||||||
|
{
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
no_peer:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
GST_UNLOCK (realpad);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pad_get_filter_caps:
|
||||||
|
* @pad: a real #GstPad.
|
||||||
|
*
|
||||||
|
* Gets the capabilities of filter that currently configured on @pad
|
||||||
|
* and its peer.
|
||||||
|
*
|
||||||
|
* Returns: the filter #GstCaps of the pad link. Free the caps when
|
||||||
|
* you no longer need it. This function returns NULL when the @pad has no
|
||||||
|
* peer or there is no filter configured.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*/
|
||||||
|
GstCaps *
|
||||||
|
gst_pad_get_filter_caps (GstPad * pad)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstRealPad *realpad, *peer;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||||
|
|
||||||
|
GST_PAD_REALIZE_AND_LOCK (pad, realpad, lost_ghostpad);
|
||||||
|
|
||||||
|
if (G_UNLIKELY ((peer = GST_RPAD_PEER (realpad)) == NULL))
|
||||||
|
goto no_peer;
|
||||||
|
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting filter caps",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
|
||||||
|
if ((caps = GST_RPAD_APPFILTER (realpad)) != NULL)
|
||||||
|
gst_caps_ref (caps);
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CAPS, "filter caps %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
lost_ghostpad:
|
||||||
|
{
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
no_peer:
|
||||||
|
{
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer",
|
||||||
|
GST_DEBUG_PAD_NAME (realpad));
|
||||||
|
GST_UNLOCK (realpad);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1804,33 +2148,38 @@ gst_pad_get_allowed_caps (GstPad * pad)
|
||||||
* @caps: the caps of the new buffer
|
* @caps: the caps of the new buffer
|
||||||
*
|
*
|
||||||
* Allocates a new, empty buffer optimized to push to pad @pad. This
|
* Allocates a new, empty buffer optimized to push to pad @pad. This
|
||||||
* function only works if @pad is a source pad. You need to check the
|
* function only works if @pad is a source pad and a GST_REAL_PAD and
|
||||||
* caps of the buffer after performing this function and renegotiate
|
* has a peer.
|
||||||
* to the format if needed.
|
* You need to check the caps of the buffer after performing this
|
||||||
|
* function and renegotiate to the format if needed.
|
||||||
*
|
*
|
||||||
* Returns: a new, empty #GstBuffer, or NULL if wrong parameters
|
* Returns: a new, empty #GstBuffer, or NULL if wrong parameters
|
||||||
* were provided.
|
* were provided or the peer pad is not able to provide a buffer
|
||||||
|
* that can be handled by the caller.
|
||||||
*
|
*
|
||||||
* MT safe.
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
GstBuffer *
|
GstBuffer *
|
||||||
gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size)
|
gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstRealPad *peer;
|
GstRealPad *peer;
|
||||||
GstBuffer *result = NULL;
|
GstBuffer *result = NULL;
|
||||||
GstPadBufferAllocFunction bufferallocfunc;
|
GstPadBufferAllocFunction bufferallocfunc;
|
||||||
GstCaps *caps;
|
gboolean caps_changed;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
|
g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
|
||||||
g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
|
g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
|
||||||
|
|
||||||
GST_LOCK (pad);
|
GST_LOCK (pad);
|
||||||
if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
|
if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
|
||||||
goto fallback;
|
goto no_peer;
|
||||||
|
|
||||||
if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL))
|
if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) {
|
||||||
|
GST_UNLOCK (pad);
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_ref (GST_OBJECT_CAST (peer));
|
||||||
GST_UNLOCK (pad);
|
GST_UNLOCK (pad);
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_PADS,
|
GST_CAT_DEBUG (GST_CAT_PADS,
|
||||||
|
@ -1838,29 +2187,48 @@ gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size)
|
||||||
GST_DEBUG_FUNCPTR_NAME (bufferallocfunc),
|
GST_DEBUG_FUNCPTR_NAME (bufferallocfunc),
|
||||||
&bufferallocfunc, GST_DEBUG_PAD_NAME (peer));
|
&bufferallocfunc, GST_DEBUG_PAD_NAME (peer));
|
||||||
|
|
||||||
result =
|
result = bufferallocfunc (GST_PAD_CAST (peer), offset, size, caps);
|
||||||
bufferallocfunc (GST_PAD_CAST (peer), offset, size, GST_PAD_CAPS (pad));
|
|
||||||
|
gst_object_unref (GST_OBJECT_CAST (peer));
|
||||||
|
|
||||||
if (G_UNLIKELY (result == NULL)) {
|
if (G_UNLIKELY (result == NULL)) {
|
||||||
GST_LOCK (pad);
|
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME, move capnego this into a base class? */
|
||||||
|
caps = GST_BUFFER_CAPS (result);
|
||||||
|
caps_changed = caps && caps != GST_RPAD_CAPS (pad);
|
||||||
|
/* we got a new datatype on the pad, see if it can handle it */
|
||||||
|
if (G_UNLIKELY (caps_changed)) {
|
||||||
|
if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps)))
|
||||||
|
goto not_negotiated;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
no_peer:
|
||||||
|
{
|
||||||
|
/* pad has no peer */
|
||||||
|
GST_CAT_DEBUG (GST_CAT_PADS,
|
||||||
|
"%s:%s called bufferallocfunc but had no peer, returning NULL",
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
GST_UNLOCK (pad);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/* fallback case, allocate a buffer of our own, add pad caps. */
|
/* fallback case, allocate a buffer of our own, add pad caps. */
|
||||||
fallback:
|
fallback:
|
||||||
{
|
{
|
||||||
caps = GST_PAD_CAPS (pad);
|
|
||||||
gst_caps_ref (caps);
|
|
||||||
GST_UNLOCK (pad);
|
|
||||||
|
|
||||||
result = gst_buffer_new_and_alloc (size);
|
result = gst_buffer_new_and_alloc (size);
|
||||||
gst_buffer_set_caps (result, caps);
|
gst_buffer_set_caps (result, caps);
|
||||||
gst_caps_unref (caps);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
not_negotiated:
|
||||||
|
{
|
||||||
|
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||||
|
"alloc function retured unacceptable buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2119,6 +2487,8 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
|
||||||
GstRealPad *peer;
|
GstRealPad *peer;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstPadChainFunction chainfunc;
|
GstPadChainFunction chainfunc;
|
||||||
|
GstCaps *caps;
|
||||||
|
gboolean caps_changed;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
|
g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
|
||||||
g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC,
|
g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC,
|
||||||
|
@ -2126,8 +2496,8 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
|
||||||
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
|
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
|
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
|
||||||
|
|
||||||
GST_LOCK (pad);
|
|
||||||
|
|
||||||
|
GST_LOCK (pad);
|
||||||
while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
|
while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
|
||||||
handle_pad_block (GST_REAL_PAD_CAST (pad));
|
handle_pad_block (GST_REAL_PAD_CAST (pad));
|
||||||
|
|
||||||
|
@ -2140,6 +2510,15 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
|
||||||
gst_object_ref (GST_OBJECT_CAST (peer));
|
gst_object_ref (GST_OBJECT_CAST (peer));
|
||||||
GST_UNLOCK (pad);
|
GST_UNLOCK (pad);
|
||||||
|
|
||||||
|
/* FIXME, move capnego this into a base class? */
|
||||||
|
caps = GST_BUFFER_CAPS (buffer);
|
||||||
|
caps_changed = caps && caps != GST_RPAD_CAPS (peer);
|
||||||
|
/* we got a new datatype on the peer pad, see if it can handle it */
|
||||||
|
if (G_UNLIKELY (caps_changed)) {
|
||||||
|
if (G_UNLIKELY (!gst_pad_configure_sink (GST_PAD_CAST (peer), caps)))
|
||||||
|
goto not_negotiated;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOTE: we read the peer chainfunc unlocked.
|
/* NOTE: we read the peer chainfunc unlocked.
|
||||||
* we cannot hold the lock for the peer so we might send
|
* we cannot hold the lock for the peer so we might send
|
||||||
* the data to the wrong function. This is not really a
|
* the data to the wrong function. This is not really a
|
||||||
|
@ -2160,83 +2539,33 @@ gst_pad_push (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
/* ERROR recovery here */
|
/* ERROR recovery here */
|
||||||
not_linked:
|
not_linked:
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
{
|
||||||
"pushing, but it was not linked");
|
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||||
GST_UNLOCK_RETURN (pad, GST_FLOW_NOT_CONNECTED);
|
"pushing, but it was not linked");
|
||||||
|
GST_UNLOCK_RETURN (pad, GST_FLOW_NOT_CONNECTED);
|
||||||
|
}
|
||||||
not_active:
|
not_active:
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but it was inactive");
|
{
|
||||||
GST_UNLOCK_RETURN (pad, GST_FLOW_WRONG_STATE);
|
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||||
|
"pushing, but it was inactive");
|
||||||
|
GST_UNLOCK_RETURN (pad, GST_FLOW_WRONG_STATE);
|
||||||
|
}
|
||||||
|
not_negotiated:
|
||||||
|
{
|
||||||
|
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||||
|
"pushing buffer but peer did not accept");
|
||||||
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
}
|
||||||
no_function:
|
no_function:
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but not chainhandler");
|
{
|
||||||
g_warning ("push on pad %s:%s but it has no chainhandler, file a bug.",
|
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||||
GST_DEBUG_PAD_NAME (peer));
|
"pushing, but not chainhandler");
|
||||||
gst_object_unref (GST_OBJECT (peer));
|
GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
|
||||||
return GST_FLOW_ERROR;
|
("push on pad %s:%s but the peer pad %s:%s has no chainfunction",
|
||||||
}
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer)));
|
||||||
|
gst_object_unref (GST_OBJECT (peer));
|
||||||
/**
|
return GST_FLOW_ERROR;
|
||||||
* gst_pad_pull:
|
}
|
||||||
* @pad: a sink #GstPad.
|
|
||||||
* @buffer: a pointer to hold the #GstBuffer.
|
|
||||||
*
|
|
||||||
* Pulls a buffer from the peer pad. May only be called by @pad's
|
|
||||||
* parent.
|
|
||||||
*
|
|
||||||
* Returns: a #GstFlowReturn from the peer pad.
|
|
||||||
*
|
|
||||||
* MT safe.
|
|
||||||
*/
|
|
||||||
GstFlowReturn
|
|
||||||
gst_pad_pull (GstPad * pad, GstBuffer ** buffer)
|
|
||||||
{
|
|
||||||
GstRealPad *peer;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
GstPadGetFunction getfunc;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR);
|
|
||||||
g_return_val_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK,
|
|
||||||
GST_FLOW_ERROR);
|
|
||||||
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
|
|
||||||
|
|
||||||
GST_LOCK (pad);
|
|
||||||
|
|
||||||
while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad)))
|
|
||||||
handle_pad_block (GST_REAL_PAD_CAST (pad));
|
|
||||||
|
|
||||||
if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL))
|
|
||||||
goto not_connected;
|
|
||||||
|
|
||||||
gst_object_ref (GST_OBJECT_CAST (peer));
|
|
||||||
GST_UNLOCK (pad);
|
|
||||||
|
|
||||||
/* see note in above function */
|
|
||||||
if (G_UNLIKELY ((getfunc = peer->getfunc) == NULL))
|
|
||||||
goto no_function;
|
|
||||||
|
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
|
||||||
"calling getfunc %s of peer pad %s:%s",
|
|
||||||
GST_DEBUG_FUNCPTR_NAME (getfunc), GST_DEBUG_PAD_NAME (peer));
|
|
||||||
|
|
||||||
ret = getfunc (GST_PAD_CAST (peer), buffer);
|
|
||||||
|
|
||||||
gst_object_unref (GST_OBJECT_CAST (peer));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* ERROR recovery here */
|
|
||||||
not_connected:
|
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
|
||||||
"pulling, but it was not linked");
|
|
||||||
GST_UNLOCK_RETURN (pad, GST_FLOW_NOT_CONNECTED);
|
|
||||||
|
|
||||||
no_function:
|
|
||||||
GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
|
|
||||||
("pull on pad %s:%s but the peer pad %s:%s has no getfunc",
|
|
||||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer)));
|
|
||||||
gst_object_unref (GST_OBJECT (peer));
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
92
gst/gstpad.h
92
gst/gstpad.h
|
@ -32,6 +32,7 @@
|
||||||
#include <gst/gstevent.h>
|
#include <gst/gstevent.h>
|
||||||
#include <gst/gstprobe.h>
|
#include <gst/gstprobe.h>
|
||||||
#include <gst/gstquery.h>
|
#include <gst/gstquery.h>
|
||||||
|
#include <gst/gsttask.h>
|
||||||
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -109,6 +110,12 @@ typedef enum {
|
||||||
GST_FLOW_NOT_SUPPORTED = -6 /* function not supported */
|
GST_FLOW_NOT_SUPPORTED = -6 /* function not supported */
|
||||||
} GstFlowReturn;
|
} GstFlowReturn;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_ACTIVATE_NONE,
|
||||||
|
GST_ACTIVATE_PUSH,
|
||||||
|
GST_ACTIVATE_PULL,
|
||||||
|
} GstActivateMode;
|
||||||
|
|
||||||
/* convenience functions */
|
/* convenience functions */
|
||||||
#ifdef G_HAVE_ISO_VARARGS
|
#ifdef G_HAVE_ISO_VARARGS
|
||||||
#define GST_PAD_QUERY_TYPE_FUNCTION(functionname, ...) GST_QUERY_TYPE_FUNCTION (GstPad *, functionname, __VA_ARGS__);
|
#define GST_PAD_QUERY_TYPE_FUNCTION(functionname, ...) GST_QUERY_TYPE_FUNCTION (GstPad *, functionname, __VA_ARGS__);
|
||||||
|
@ -125,10 +132,10 @@ typedef enum {
|
||||||
typedef gboolean (*GstPadActivateFunction) (GstPad *pad, gboolean active);
|
typedef gboolean (*GstPadActivateFunction) (GstPad *pad, gboolean active);
|
||||||
|
|
||||||
/* data passing */
|
/* data passing */
|
||||||
|
typedef gboolean (*GstPadLoopFunction) (GstPad *pad);
|
||||||
typedef GstFlowReturn (*GstPadChainFunction) (GstPad *pad, GstBuffer *buffer);
|
typedef GstFlowReturn (*GstPadChainFunction) (GstPad *pad, GstBuffer *buffer);
|
||||||
typedef GstFlowReturn (*GstPadGetFunction) (GstPad *pad, GstBuffer **buffer);
|
|
||||||
typedef GstFlowReturn (*GstPadGetRangeFunction) (GstPad *pad, guint64 offset,
|
typedef GstFlowReturn (*GstPadGetRangeFunction) (GstPad *pad, guint64 offset,
|
||||||
guint64 length, GstBuffer **buffer);
|
guint length, GstBuffer **buffer);
|
||||||
typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event);
|
typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event);
|
||||||
|
|
||||||
/* convert/query/format functions */
|
/* convert/query/format functions */
|
||||||
|
@ -148,6 +155,9 @@ typedef void (*GstPadUnlinkFunction) (GstPad *pad);
|
||||||
|
|
||||||
/* caps nego */
|
/* caps nego */
|
||||||
typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad);
|
typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad);
|
||||||
|
typedef gboolean (*GstPadSetCapsFunction) (GstPad *pad, GstCaps *caps);
|
||||||
|
typedef gboolean (*GstPadAcceptCapsFunction) (GstPad *pad, GstCaps *caps);
|
||||||
|
typedef GstCaps* (*GstPadFixateCapsFunction) (GstPad *pad, GstCaps *caps);
|
||||||
typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size,
|
typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size,
|
||||||
GstCaps *caps);
|
GstCaps *caps);
|
||||||
/* misc */
|
/* misc */
|
||||||
|
@ -162,12 +172,13 @@ typedef enum {
|
||||||
} GstPadDirection;
|
} GstPadDirection;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_PAD_DISABLED = GST_OBJECT_FLAG_LAST,
|
GST_PAD_ACTIVE = GST_OBJECT_FLAG_LAST,
|
||||||
GST_PAD_BLOCKED,
|
GST_PAD_BLOCKED,
|
||||||
GST_PAD_NEGOTIATING,
|
GST_PAD_FLUSHING,
|
||||||
GST_PAD_DISPATCHING,
|
GST_PAD_IN_GETCAPS,
|
||||||
|
GST_PAD_IN_SETCAPS,
|
||||||
|
|
||||||
GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4
|
GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 8
|
||||||
} GstPadFlags;
|
} GstPadFlags;
|
||||||
|
|
||||||
struct _GstPad {
|
struct _GstPad {
|
||||||
|
@ -196,6 +207,7 @@ struct _GstRealPad {
|
||||||
/* streaming lock and cond */
|
/* streaming lock and cond */
|
||||||
GMutex *stream_lock;
|
GMutex *stream_lock;
|
||||||
GCond *stream_cond;
|
GCond *stream_cond;
|
||||||
|
GstTask *task;
|
||||||
|
|
||||||
/*< public >*/ /* with LOCK */
|
/*< public >*/ /* with LOCK */
|
||||||
/* block cond, mutex is from the object */
|
/* block cond, mutex is from the object */
|
||||||
|
@ -207,9 +219,13 @@ struct _GstRealPad {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstCaps *appfilter;
|
GstCaps *appfilter;
|
||||||
GstPadGetCapsFunction getcapsfunc;
|
GstPadGetCapsFunction getcapsfunc;
|
||||||
|
GstPadSetCapsFunction setcapsfunc;
|
||||||
|
GstPadAcceptCapsFunction acceptcapsfunc;
|
||||||
|
GstPadFixateCapsFunction fixatecapsfunc;
|
||||||
|
|
||||||
GstPadActivateFunction activatefunc;
|
GstPadActivateFunction activatefunc;
|
||||||
|
|
||||||
|
/* pad link */
|
||||||
GstPadLinkFunction linkfunc;
|
GstPadLinkFunction linkfunc;
|
||||||
GstPadUnlinkFunction unlinkfunc;
|
GstPadUnlinkFunction unlinkfunc;
|
||||||
GstRealPad *peer;
|
GstRealPad *peer;
|
||||||
|
@ -217,13 +233,14 @@ struct _GstRealPad {
|
||||||
gpointer sched_private;
|
gpointer sched_private;
|
||||||
|
|
||||||
/* data transport functions */
|
/* data transport functions */
|
||||||
|
GstPadLoopFunction loopfunc;
|
||||||
GstPadChainFunction chainfunc;
|
GstPadChainFunction chainfunc;
|
||||||
GstPadGetFunction getfunc;
|
|
||||||
GstPadGetRangeFunction getrangefunc;
|
GstPadGetRangeFunction getrangefunc;
|
||||||
GstPadEventFunction eventfunc;
|
GstPadEventFunction eventfunc;
|
||||||
|
|
||||||
GstPadEventMaskFunction eventmaskfunc;
|
GstPadEventMaskFunction eventmaskfunc;
|
||||||
|
|
||||||
|
/* ghostpads */
|
||||||
GList *ghostpads;
|
GList *ghostpads;
|
||||||
guint32 ghostpads_cookie;
|
guint32 ghostpads_cookie;
|
||||||
|
|
||||||
|
@ -277,12 +294,10 @@ struct _GstGhostPadClass {
|
||||||
|
|
||||||
/* GstRealPad */
|
/* GstRealPad */
|
||||||
#define GST_RPAD_DIRECTION(pad) (GST_REAL_PAD_CAST(pad)->direction)
|
#define GST_RPAD_DIRECTION(pad) (GST_REAL_PAD_CAST(pad)->direction)
|
||||||
#define GST_RPAD_CAPS(pad) (GST_REAL_PAD_CAST(pad)->caps)
|
#define GST_RPAD_TASK(pad) (GST_REAL_PAD_CAST(pad)->task)
|
||||||
#define GST_RPAD_APPFILTER(pad) (GST_REAL_PAD_CAST(pad)->appfilter)
|
|
||||||
#define GST_RPAD_PEER(pad) (GST_REAL_PAD_CAST(pad)->peer)
|
|
||||||
#define GST_RPAD_ACTIVATEFUNC(pad) (GST_REAL_PAD_CAST(pad)->activatefunc)
|
#define GST_RPAD_ACTIVATEFUNC(pad) (GST_REAL_PAD_CAST(pad)->activatefunc)
|
||||||
|
#define GST_RPAD_LOOPFUNC(pad) (GST_REAL_PAD_CAST(pad)->loopfunc)
|
||||||
#define GST_RPAD_CHAINFUNC(pad) (GST_REAL_PAD_CAST(pad)->chainfunc)
|
#define GST_RPAD_CHAINFUNC(pad) (GST_REAL_PAD_CAST(pad)->chainfunc)
|
||||||
#define GST_RPAD_GETFUNC(pad) (GST_REAL_PAD_CAST(pad)->getfunc)
|
|
||||||
#define GST_RPAD_GETRANGEFUNC(pad) (GST_REAL_PAD_CAST(pad)->getrangefunc)
|
#define GST_RPAD_GETRANGEFUNC(pad) (GST_REAL_PAD_CAST(pad)->getrangefunc)
|
||||||
#define GST_RPAD_EVENTFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventfunc)
|
#define GST_RPAD_EVENTFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventfunc)
|
||||||
#define GST_RPAD_CONVERTFUNC(pad) (GST_REAL_PAD_CAST(pad)->convertfunc)
|
#define GST_RPAD_CONVERTFUNC(pad) (GST_REAL_PAD_CAST(pad)->convertfunc)
|
||||||
|
@ -292,31 +307,39 @@ struct _GstGhostPadClass {
|
||||||
#define GST_RPAD_QUERYTYPEFUNC(pad) (GST_REAL_PAD_CAST(pad)->querytypefunc)
|
#define GST_RPAD_QUERYTYPEFUNC(pad) (GST_REAL_PAD_CAST(pad)->querytypefunc)
|
||||||
#define GST_RPAD_EVENTMASKFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventmaskfunc)
|
#define GST_RPAD_EVENTMASKFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventmaskfunc)
|
||||||
|
|
||||||
|
#define GST_RPAD_PEER(pad) (GST_REAL_PAD_CAST(pad)->peer)
|
||||||
#define GST_RPAD_LINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->linkfunc)
|
#define GST_RPAD_LINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->linkfunc)
|
||||||
#define GST_RPAD_UNLINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->unlinkfunc)
|
#define GST_RPAD_UNLINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->unlinkfunc)
|
||||||
|
|
||||||
|
#define GST_RPAD_CAPS(pad) (GST_REAL_PAD_CAST(pad)->caps)
|
||||||
|
#define GST_RPAD_APPFILTER(pad) (GST_REAL_PAD_CAST(pad)->appfilter)
|
||||||
#define GST_RPAD_GETCAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->getcapsfunc)
|
#define GST_RPAD_GETCAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->getcapsfunc)
|
||||||
|
#define GST_RPAD_SETCAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->setcapsfunc)
|
||||||
|
#define GST_RPAD_ACCEPTCAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->acceptcapsfunc)
|
||||||
|
#define GST_RPAD_FIXATECAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->fixatecapsfunc)
|
||||||
|
|
||||||
#define GST_RPAD_BUFFERALLOCFUNC(pad) (GST_REAL_PAD_CAST(pad)->bufferallocfunc)
|
#define GST_RPAD_BUFFERALLOCFUNC(pad) (GST_REAL_PAD_CAST(pad)->bufferallocfunc)
|
||||||
|
|
||||||
#define GST_RPAD_IS_LINKED(pad) (GST_RPAD_PEER(pad) != NULL)
|
#define GST_RPAD_IS_LINKED(pad) (GST_RPAD_PEER(pad) != NULL)
|
||||||
#define GST_RPAD_IS_ACTIVE(pad) (!GST_FLAG_IS_SET(pad, GST_PAD_DISABLED))
|
#define GST_RPAD_IS_ACTIVE(pad) (GST_FLAG_IS_SET (pad, GST_PAD_ACTIVE))
|
||||||
#define GST_RPAD_IS_BLOCKED(pad) (GST_FLAG_IS_SET (pad, GST_PAD_BLOCKED))
|
#define GST_RPAD_IS_BLOCKED(pad) (GST_FLAG_IS_SET (pad, GST_PAD_BLOCKED))
|
||||||
#define GST_RPAD_IS_NEGOTIATING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING))
|
#define GST_RPAD_IS_FLUSHING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
|
||||||
#define GST_RPAD_IS_DISPATCHING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_DISPATCHING))
|
#define GST_RPAD_IS_IN_GETCAPS(pad) (GST_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
|
||||||
|
#define GST_RPAD_IS_IN_SETCAPS(pad) (GST_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
|
||||||
#define GST_RPAD_IS_USABLE(pad) (GST_RPAD_IS_LINKED (pad) && \
|
#define GST_RPAD_IS_USABLE(pad) (GST_RPAD_IS_LINKED (pad) && \
|
||||||
GST_RPAD_IS_ACTIVE(pad) && GST_RPAD_IS_ACTIVE(GST_RPAD_PEER (pad)))
|
GST_RPAD_IS_ACTIVE(pad) && GST_RPAD_IS_ACTIVE(GST_RPAD_PEER (pad)))
|
||||||
#define GST_RPAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->gethandler != NULL)
|
|
||||||
#define GST_RPAD_IS_SRC(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC)
|
#define GST_RPAD_IS_SRC(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC)
|
||||||
#define GST_RPAD_IS_SINK(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK)
|
#define GST_RPAD_IS_SINK(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK)
|
||||||
|
|
||||||
#define GST_STREAM_GET_LOCK(pad) (GST_PAD_REALIZE(pad)->stream_lock)
|
#define GST_STREAM_GET_LOCK(pad) (GST_PAD_REALIZE(pad)->stream_lock)
|
||||||
#define GST_STREAM_LOCK(pad) (g_mutex_lock(GST_STREAM_GET_LOCK(pad)))
|
#define GST_STREAM_LOCK(pad) (g_mutex_lock(GST_STREAM_GET_LOCK(pad)))
|
||||||
#define GST_STREAM_TRYLOCK(pad) (g_mutex_trylock(GST_STREAM_GET_LOCK(pad)))
|
#define GST_STREAM_TRYLOCK(pad) (g_mutex_trylock(GST_STREAM_GET_LOCK(pad)))
|
||||||
#define GST_STREAM_UNLOCK(pad) (g_mutex_unlock(GST_STREAM_GET_LOCK(pad)))
|
#define GST_STREAM_UNLOCK(pad) (g_mutex_unlock(GST_STREAM_GET_LOCK(pad)))
|
||||||
#define GST_STREAM_GET_COND(pad) (GST_PAD_REALIZE(pad)->stream_cond)
|
#define GST_STREAM_GET_COND(pad) (GST_PAD_REALIZE(pad)->stream_cond)
|
||||||
|
|
||||||
#define GST_PAD_BLOCK_GET_COND(pad) (GST_PAD_REALIZE(pad)->block_cond)
|
#define GST_PAD_BLOCK_GET_COND(pad) (GST_PAD_REALIZE(pad)->block_cond)
|
||||||
#define GST_PAD_BLOCK_WAIT(pad) (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_GET_LOCK (pad)))
|
#define GST_PAD_BLOCK_WAIT(pad) (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_GET_LOCK (pad)))
|
||||||
#define GST_PAD_BLOCK_SIGNAL(pad) (g_cond_signal(GST_PAD_BLOCK_GET_COND (pad)))
|
#define GST_PAD_BLOCK_SIGNAL(pad) (g_cond_signal(GST_PAD_BLOCK_GET_COND (pad)))
|
||||||
|
|
||||||
/* GstGhostPad */
|
/* GstGhostPad */
|
||||||
#define GST_GPAD_REALPAD(pad) (((GstGhostPad *)(pad))->realpad)
|
#define GST_GPAD_REALPAD(pad) (((GstGhostPad *)(pad))->realpad)
|
||||||
|
@ -333,7 +356,8 @@ struct _GstGhostPadClass {
|
||||||
#define GST_PAD_IS_ACTIVE(pad) (GST_RPAD_IS_ACTIVE(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_ACTIVE(pad) (GST_RPAD_IS_ACTIVE(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_IS_BLOCKED(pad) (GST_RPAD_IS_BLOCKED(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_BLOCKED(pad) (GST_RPAD_IS_BLOCKED(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_IS_NEGOTIATING(pad) (GST_RPAD_IS_NEGOTIATING(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_NEGOTIATING(pad) (GST_RPAD_IS_NEGOTIATING(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_IS_DISPATCHING(pad) (GST_RPAD_IS_DISPATCHING(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_IN_GETCAPS(pad) (GST_RPAD_IS_IN_GETCAPS(GST_PAD_REALIZE(pad)))
|
||||||
|
#define GST_PAD_IS_IN_SETCAPS(pad) (GST_RPAD_IS_IN_SETCAPS(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_IS_USABLE(pad) (GST_RPAD_IS_USABLE(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_USABLE(pad) (GST_RPAD_IS_USABLE(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_CAN_PULL(pad) (GST_RPAD_CAN_PULL(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_CAN_PULL(pad) (GST_RPAD_CAN_PULL(GST_PAD_REALIZE(pad)))
|
||||||
#define GST_PAD_IS_SRC(pad) (GST_RPAD_IS_SRC(GST_PAD_REALIZE(pad)))
|
#define GST_PAD_IS_SRC(pad) (GST_RPAD_IS_SRC(GST_PAD_REALIZE(pad)))
|
||||||
|
@ -433,13 +457,14 @@ gpointer gst_pad_get_element_private (GstPad *pad);
|
||||||
GstPadTemplate* gst_pad_get_pad_template (GstPad *pad);
|
GstPadTemplate* gst_pad_get_pad_template (GstPad *pad);
|
||||||
|
|
||||||
void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc);
|
void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc);
|
||||||
GstBuffer* gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size);
|
GstBuffer* gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size,
|
||||||
|
GstCaps *caps);
|
||||||
|
|
||||||
/* data passing setup functions */
|
/* data passing setup functions */
|
||||||
void gst_pad_set_activate_function (GstPad *pad, GstPadActivateFunction activate);
|
void gst_pad_set_activate_function (GstPad *pad, GstPadActivateFunction activate);
|
||||||
|
void gst_pad_set_loop_function (GstPad *pad, GstPadLoopFunction loop);
|
||||||
void gst_pad_set_chain_function (GstPad *pad, GstPadChainFunction chain);
|
void gst_pad_set_chain_function (GstPad *pad, GstPadChainFunction chain);
|
||||||
void gst_pad_set_get_function (GstPad *pad, GstPadGetFunction get);
|
void gst_pad_set_getrange_function (GstPad *pad, GstPadGetRangeFunction get);
|
||||||
void gst_pad_set_get_range_function (GstPad *pad, GstPadGetRangeFunction get);
|
|
||||||
|
|
||||||
void gst_pad_set_event_function (GstPad *pad, GstPadEventFunction event);
|
void gst_pad_set_event_function (GstPad *pad, GstPadEventFunction event);
|
||||||
void gst_pad_set_event_mask_function (GstPad *pad, GstPadEventMaskFunction mask_func);
|
void gst_pad_set_event_mask_function (GstPad *pad, GstPadEventMaskFunction mask_func);
|
||||||
|
@ -465,16 +490,25 @@ GstPad* gst_pad_realize (GstPad *pad);
|
||||||
|
|
||||||
/* capsnego functions */
|
/* capsnego functions */
|
||||||
void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps);
|
void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps);
|
||||||
|
void gst_pad_set_acceptcaps_function (GstPad *pad, GstPadAcceptCapsFunction acceptcaps);
|
||||||
|
void gst_pad_set_fixatecaps_function (GstPad *pad, GstPadFixateCapsFunction fixatecaps);
|
||||||
|
void gst_pad_set_setcaps_function (GstPad *pad, GstPadSetCapsFunction setcaps);
|
||||||
|
|
||||||
G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad);
|
G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad);
|
||||||
|
|
||||||
GstCaps * gst_pad_get_allowed_caps (GstPad * pad);
|
/* capsnego function for connected/unconnected pads */
|
||||||
GstCaps * gst_pad_get_caps (GstPad * pad);
|
GstCaps * gst_pad_get_caps (GstPad * pad);
|
||||||
|
GstCaps* gst_pad_fixate_caps (GstPad * pad, GstCaps *caps);
|
||||||
|
gboolean gst_pad_accept_caps (GstPad * pad, GstCaps *caps);
|
||||||
gboolean gst_pad_set_caps (GstPad * pad, GstCaps *caps);
|
gboolean gst_pad_set_caps (GstPad * pad, GstCaps *caps);
|
||||||
|
|
||||||
|
/* capsnego for connected pads */
|
||||||
|
GstCaps * gst_pad_get_allowed_caps (GstPad * srcpad);
|
||||||
|
GstCaps * gst_pad_get_negotiated_caps (GstPad * pad);
|
||||||
|
GstCaps * gst_pad_get_filter_caps (GstPad * pad);
|
||||||
|
|
||||||
/* data passing functions */
|
/* data passing functions */
|
||||||
GstFlowReturn gst_pad_push (GstPad *pad, GstBuffer *buffer);
|
GstFlowReturn gst_pad_push (GstPad *pad, GstBuffer *buffer);
|
||||||
GstFlowReturn gst_pad_pull (GstPad *pad, GstBuffer **buffer);
|
|
||||||
GstFlowReturn gst_pad_pull_range (GstPad *pad, guint64 offset, guint size,
|
GstFlowReturn gst_pad_pull_range (GstPad *pad, guint64 offset, guint size,
|
||||||
GstBuffer **buffer);
|
GstBuffer **buffer);
|
||||||
gboolean gst_pad_push_event (GstPad *pad, GstEvent *event);
|
gboolean gst_pad_push_event (GstPad *pad, GstEvent *event);
|
||||||
|
|
|
@ -116,25 +116,28 @@ static void
|
||||||
gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
|
gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
|
||||||
{
|
{
|
||||||
GstPipeline *pipeline = GST_PIPELINE (instance);
|
GstPipeline *pipeline = GST_PIPELINE (instance);
|
||||||
|
GstBus *bus;
|
||||||
|
GstScheduler *scheduler;
|
||||||
|
|
||||||
/* get an instance of the default scheduler */
|
/* get an instance of the default scheduler */
|
||||||
pipeline->scheduler =
|
scheduler = gst_scheduler_factory_make (NULL, GST_ELEMENT (pipeline));
|
||||||
gst_scheduler_factory_make (NULL, GST_ELEMENT (pipeline));
|
|
||||||
|
|
||||||
/* FIXME need better error handling */
|
/* FIXME need better error handling */
|
||||||
if (pipeline->scheduler == NULL) {
|
if (scheduler == NULL) {
|
||||||
const gchar *name = gst_scheduler_factory_get_default_name ();
|
const gchar *name = gst_scheduler_factory_get_default_name ();
|
||||||
|
|
||||||
g_error ("Critical error: could not get scheduler \"%s\"\n"
|
g_error ("Critical error: could not get scheduler \"%s\"\n"
|
||||||
"Are you sure you have a registry ?\n"
|
"Are you sure you have a registry ?\n"
|
||||||
"Run gst-register as root if you haven't done so yet.", name);
|
"Run gst-register as root if you haven't done so yet.", name);
|
||||||
}
|
}
|
||||||
pipeline->bus = g_object_new (gst_bus_get_type (), NULL);
|
bus = g_object_new (gst_bus_get_type (), NULL);
|
||||||
gst_bus_set_sync_handler (pipeline->bus,
|
gst_bus_set_sync_handler (bus,
|
||||||
(GstBusSyncHandler) pipeline_bus_handler, pipeline);
|
(GstBusSyncHandler) pipeline_bus_handler, pipeline);
|
||||||
pipeline->eosed = NULL;
|
pipeline->eosed = NULL;
|
||||||
/* we are our own manager */
|
/* we are our own manager */
|
||||||
GST_ELEMENT_MANAGER (pipeline) = pipeline;
|
GST_ELEMENT_MANAGER (pipeline) = pipeline;
|
||||||
|
gst_element_set_bus (GST_ELEMENT (pipeline), bus);
|
||||||
|
gst_element_set_scheduler (GST_ELEMENT (pipeline), scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -142,11 +145,7 @@ gst_pipeline_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GstPipeline *pipeline = GST_PIPELINE (object);
|
GstPipeline *pipeline = GST_PIPELINE (object);
|
||||||
|
|
||||||
g_assert (GST_IS_SCHEDULER (pipeline->scheduler));
|
gst_scheduler_reset (GST_ELEMENT_SCHEDULER (object));
|
||||||
|
|
||||||
gst_scheduler_reset (pipeline->scheduler);
|
|
||||||
gst_object_replace ((GstObject **) & pipeline->bus, NULL);
|
|
||||||
gst_object_replace ((GstObject **) & pipeline->scheduler, NULL);
|
|
||||||
gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
|
gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
@ -273,7 +272,7 @@ gst_pipeline_change_state (GstElement * element)
|
||||||
|
|
||||||
switch (GST_STATE_TRANSITION (element)) {
|
switch (GST_STATE_TRANSITION (element)) {
|
||||||
case GST_STATE_NULL_TO_READY:
|
case GST_STATE_NULL_TO_READY:
|
||||||
gst_scheduler_setup (pipeline->scheduler);
|
gst_scheduler_setup (GST_ELEMENT_SCHEDULER (pipeline));
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_PAUSED:
|
case GST_STATE_READY_TO_PAUSED:
|
||||||
gst_element_set_clock (element, gst_element_get_clock (element));
|
gst_element_set_clock (element, gst_element_get_clock (element));
|
||||||
|
@ -314,7 +313,7 @@ gst_pipeline_change_state (GstElement * element)
|
||||||
GstScheduler *
|
GstScheduler *
|
||||||
gst_pipeline_get_scheduler (GstPipeline * pipeline)
|
gst_pipeline_get_scheduler (GstPipeline * pipeline)
|
||||||
{
|
{
|
||||||
return pipeline->scheduler;
|
return gst_element_get_scheduler (GST_ELEMENT (pipeline));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,7 +327,7 @@ gst_pipeline_get_scheduler (GstPipeline * pipeline)
|
||||||
GstBus *
|
GstBus *
|
||||||
gst_pipeline_get_bus (GstPipeline * pipeline)
|
gst_pipeline_get_bus (GstPipeline * pipeline)
|
||||||
{
|
{
|
||||||
return pipeline->bus;
|
return gst_element_get_bus (GST_ELEMENT (pipeline));
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstClock *
|
static GstClock *
|
||||||
|
@ -438,18 +437,3 @@ gst_pipeline_auto_clock (GstPipeline * pipeline)
|
||||||
|
|
||||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
|
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_pipeline_post_message:
|
|
||||||
* @pipeline: the pipeline
|
|
||||||
* @message: the message
|
|
||||||
*
|
|
||||||
* Post a message on the message bus of this pipeline.
|
|
||||||
*
|
|
||||||
* Returns: TRUE if the message could be posted.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_pipeline_post_message (GstPipeline * pipeline, GstMessage * message)
|
|
||||||
{
|
|
||||||
return gst_bus_post (pipeline->bus, message);
|
|
||||||
}
|
|
||||||
|
|
|
@ -48,8 +48,6 @@ typedef enum {
|
||||||
struct _GstPipeline {
|
struct _GstPipeline {
|
||||||
GstBin bin;
|
GstBin bin;
|
||||||
|
|
||||||
GstBus *bus;
|
|
||||||
GstScheduler *scheduler;
|
|
||||||
GstClock *fixed_clock; /* fixed clock if any */
|
GstClock *fixed_clock; /* fixed clock if any */
|
||||||
|
|
||||||
GList *eosed; /* list of elements that posted EOS */
|
GList *eosed; /* list of elements that posted EOS */
|
||||||
|
@ -68,13 +66,12 @@ GstElement* gst_pipeline_new (const gchar *name);
|
||||||
|
|
||||||
GstScheduler* gst_pipeline_get_scheduler (GstPipeline *pipeline);
|
GstScheduler* gst_pipeline_get_scheduler (GstPipeline *pipeline);
|
||||||
GstBus* gst_pipeline_get_bus (GstPipeline *pipeline);
|
GstBus* gst_pipeline_get_bus (GstPipeline *pipeline);
|
||||||
|
|
||||||
void gst_pipeline_use_clock (GstPipeline *pipeline, GstClock *clock);
|
void gst_pipeline_use_clock (GstPipeline *pipeline, GstClock *clock);
|
||||||
void gst_pipeline_set_clock (GstPipeline *pipeline, GstClock *clock);
|
void gst_pipeline_set_clock (GstPipeline *pipeline, GstClock *clock);
|
||||||
GstClock* gst_pipeline_get_clock (GstPipeline *pipeline);
|
GstClock* gst_pipeline_get_clock (GstPipeline *pipeline);
|
||||||
void gst_pipeline_auto_clock (GstPipeline *pipeline);
|
void gst_pipeline_auto_clock (GstPipeline *pipeline);
|
||||||
|
|
||||||
gboolean gst_pipeline_post_message (GstPipeline *pipeline, GstMessage *message);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_PIPELINE_H__ */
|
#endif /* __GST_PIPELINE_H__ */
|
||||||
|
|
|
@ -125,9 +125,9 @@ static void gst_queue_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_queue_get (GstPad * pad, GstBuffer ** buffer);
|
|
||||||
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
||||||
guint size, GstCaps * caps);
|
guint size, GstCaps * caps);
|
||||||
|
static gboolean gst_queue_loop (GstPad * pad);
|
||||||
|
|
||||||
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ gst_queue_init (GstQueue * queue)
|
||||||
queue->srcpad =
|
queue->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
||||||
"src");
|
"src");
|
||||||
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
|
gst_pad_set_loop_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_loop));
|
||||||
gst_pad_set_activate_function (queue->srcpad,
|
gst_pad_set_activate_function (queue->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_queue_src_activate));
|
GST_DEBUG_FUNCPTR (gst_queue_src_activate));
|
||||||
gst_pad_set_link_function (queue->srcpad,
|
gst_pad_set_link_function (queue->srcpad,
|
||||||
|
@ -433,8 +433,6 @@ gst_queue_locked_flush (GstQueue * queue)
|
||||||
while (!g_queue_is_empty (queue->queue)) {
|
while (!g_queue_is_empty (queue->queue)) {
|
||||||
GstData *data = g_queue_pop_head (queue->queue);
|
GstData *data = g_queue_pop_head (queue->queue);
|
||||||
|
|
||||||
/* First loose the reference we added when putting that data in the queue */
|
|
||||||
gst_data_unref (data);
|
|
||||||
/* Then loose another reference because we are supposed to destroy that
|
/* Then loose another reference because we are supposed to destroy that
|
||||||
data when flushing */
|
data when flushing */
|
||||||
gst_data_unref (data);
|
gst_data_unref (data);
|
||||||
|
@ -492,7 +490,6 @@ gst_queue_handle_sink_event (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_event_ref (event);
|
|
||||||
g_queue_push_tail (queue->queue, event);
|
g_queue_push_tail (queue->queue, event);
|
||||||
g_cond_signal (queue->item_add);
|
g_cond_signal (queue->item_add);
|
||||||
GST_QUEUE_MUTEX_UNLOCK;
|
GST_QUEUE_MUTEX_UNLOCK;
|
||||||
|
@ -621,11 +618,6 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put the buffer on the tail of the list. We keep a reference,
|
|
||||||
* so that the buffer is read-only while in here. There's a good
|
|
||||||
* reason to do so: we have a size and time counter, and any
|
|
||||||
* modification to the content could change any of the two. */
|
|
||||||
gst_buffer_ref (buffer);
|
|
||||||
g_queue_push_tail (queue->queue, buffer);
|
g_queue_push_tail (queue->queue, buffer);
|
||||||
|
|
||||||
/* add buffer to the statistics */
|
/* add buffer to the statistics */
|
||||||
|
@ -648,14 +640,14 @@ out_unref:
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static gboolean
|
||||||
gst_queue_get (GstPad * pad, GstBuffer ** buffer)
|
gst_queue_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstQueue *queue;
|
GstQueue *queue;
|
||||||
GstData *data;
|
GstData *data;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
gboolean result = TRUE;
|
||||||
|
|
||||||
queue = GST_QUEUE (gst_object_get_parent (GST_OBJECT (pad)));
|
queue = GST_QUEUE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
/* have to lock for thread-safety */
|
/* have to lock for thread-safety */
|
||||||
GST_QUEUE_MUTEX_LOCK;
|
GST_QUEUE_MUTEX_LOCK;
|
||||||
|
@ -696,23 +688,16 @@ restart:
|
||||||
if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE)
|
if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE)
|
||||||
queue->cur_level.time -= GST_BUFFER_DURATION (data);
|
queue->cur_level.time -= GST_BUFFER_DURATION (data);
|
||||||
|
|
||||||
*buffer = GST_BUFFER (data);
|
gst_pad_push (pad, GST_BUFFER (data));
|
||||||
} else {
|
} else {
|
||||||
if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
|
if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
|
||||||
result = GST_FLOW_WRONG_STATE;
|
result = FALSE;
|
||||||
}
|
}
|
||||||
gst_pad_push_event (queue->srcpad, GST_EVENT (data));
|
gst_pad_push_event (queue->srcpad, GST_EVENT (data));
|
||||||
if (result == GST_FLOW_OK)
|
if (result == TRUE)
|
||||||
goto restart;
|
goto restart;
|
||||||
else
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we're done, we can lose our own reference to
|
|
||||||
* the item, since we're no longer in danger. */
|
|
||||||
gst_data_unref (data);
|
|
||||||
|
|
||||||
done:
|
|
||||||
STATUS (queue, "after _get()");
|
STATUS (queue, "after _get()");
|
||||||
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del");
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del");
|
||||||
|
@ -784,37 +769,6 @@ gst_queue_handle_src_query (GstPad * pad,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_queue_loop (GstElement * element)
|
|
||||||
{
|
|
||||||
GstQueue *queue;
|
|
||||||
GstTask *task;
|
|
||||||
GstBuffer *buffer;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
g_return_if_fail (element != NULL);
|
|
||||||
g_return_if_fail (GST_IS_QUEUE (element));
|
|
||||||
|
|
||||||
queue = GST_QUEUE (element);
|
|
||||||
task = queue->task;
|
|
||||||
|
|
||||||
ret = gst_queue_get (queue->srcpad, &buffer);
|
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "stopping, get returned %d",
|
|
||||||
ret);
|
|
||||||
gst_task_stop (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ret = gst_pad_push (queue->srcpad, buffer);
|
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "stopping, push returned %d",
|
|
||||||
ret);
|
|
||||||
gst_task_stop (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_queue_src_activate (GstPad * pad, gboolean active)
|
gst_queue_src_activate (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
|
@ -825,18 +779,18 @@ gst_queue_src_activate (GstPad * pad, gboolean active)
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
if (GST_ELEMENT_MANAGER (queue)) {
|
if (GST_ELEMENT_SCHEDULER (queue)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
queue->task =
|
queue->task =
|
||||||
gst_scheduler_create_task (GST_ELEMENT_MANAGER (queue)->scheduler,
|
gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (queue),
|
||||||
(GstTaskFunction) gst_queue_loop, queue);
|
(GstTaskFunction) gst_queue_loop, pad);
|
||||||
|
|
||||||
gst_task_start (queue->task);
|
gst_task_start (queue->task);
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* step 1, unblock chain and get functions */
|
/* step 1, unblock chain and loop functions */
|
||||||
queue->interrupt = TRUE;
|
queue->interrupt = TRUE;
|
||||||
g_cond_signal (queue->item_add);
|
g_cond_signal (queue->item_add);
|
||||||
g_cond_signal (queue->item_del);
|
g_cond_signal (queue->item_del);
|
||||||
|
@ -865,8 +819,7 @@ gst_queue_change_state (GstElement * element)
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change");
|
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change");
|
||||||
|
|
||||||
/* lock the queue so another thread (not in sync with this thread's state)
|
/* lock the queue so another thread (not in sync with this thread's state)
|
||||||
* can't call this queue's _get (or whatever)
|
* can't call this queue's _loop (or whatever) */
|
||||||
*/
|
|
||||||
GST_QUEUE_MUTEX_LOCK;
|
GST_QUEUE_MUTEX_LOCK;
|
||||||
|
|
||||||
switch (GST_STATE_TRANSITION (element)) {
|
switch (GST_STATE_TRANSITION (element)) {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef void (*GstTaskFunction) (void *data);
|
typedef gboolean (*GstTaskFunction) (void *data);
|
||||||
|
|
||||||
/* --- standard type macros --- */
|
/* --- standard type macros --- */
|
||||||
#define GST_TYPE_TASK (gst_task_get_type ())
|
#define GST_TYPE_TASK (gst_task_get_type ())
|
||||||
|
|
|
@ -1294,6 +1294,16 @@ gst_pad_can_link_filtered (GstPad * srcpad, GstPad * sinkpad,
|
||||||
GST_DEBUG_PAD_NAME (realsink));
|
GST_DEBUG_PAD_NAME (realsink));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (!GST_PAD_IS_SRC (realsrc)) {
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s is not source pad, failed",
|
||||||
|
GST_DEBUG_PAD_NAME (realsrc));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!GST_PAD_IS_SINK (realsink)) {
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not sink pad, failed",
|
||||||
|
GST_DEBUG_PAD_NAME (realsink));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if (GST_PAD_PARENT (realsrc) == NULL) {
|
if (GST_PAD_PARENT (realsrc) == NULL) {
|
||||||
GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
|
GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
|
||||||
GST_DEBUG_PAD_NAME (realsrc));
|
GST_DEBUG_PAD_NAME (realsrc));
|
||||||
|
|
|
@ -236,14 +236,18 @@ static void
|
||||||
gst_thread_scheduler_func (GstThreadSchedulerTask * task,
|
gst_thread_scheduler_func (GstThreadSchedulerTask * task,
|
||||||
GstThreadScheduler * sched)
|
GstThreadScheduler * sched)
|
||||||
{
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
gst_object_ref (GST_OBJECT (task));
|
gst_object_ref (GST_OBJECT (task));
|
||||||
GST_DEBUG_OBJECT (sched, "Entering task %p, thread %p", task,
|
GST_DEBUG_OBJECT (sched, "Entering task %p, thread %p", task,
|
||||||
g_thread_self ());
|
g_thread_self ());
|
||||||
g_mutex_lock (task->lock);
|
g_mutex_lock (task->lock);
|
||||||
while (task->state == STATE_STARTED) {
|
while (G_LIKELY (task->state == STATE_STARTED)) {
|
||||||
g_mutex_unlock (task->lock);
|
g_mutex_unlock (task->lock);
|
||||||
task->func (task->data);
|
res = task->func (task->data);
|
||||||
g_mutex_lock (task->lock);
|
g_mutex_lock (task->lock);
|
||||||
|
if (G_UNLIKELY (!res))
|
||||||
|
task->state = STATE_STOPPED;
|
||||||
}
|
}
|
||||||
g_mutex_unlock (task->lock);
|
g_mutex_unlock (task->lock);
|
||||||
GST_DEBUG_OBJECT (sched, "Exit task %p, thread %p", task, g_thread_self ());
|
GST_DEBUG_OBJECT (sched, "Exit task %p, thread %p", task, g_thread_self ());
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
SUBDIRS = bytestream control dataprotocol getbits
|
SUBDIRS = control dataprotocol getbits
|
||||||
|
|
|
@ -332,7 +332,7 @@ gst_fakesink_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
gst_element_finish_preroll (GST_ELEMENT (fakesink),
|
gst_element_finish_preroll (GST_ELEMENT (fakesink),
|
||||||
GST_STREAM_GET_LOCK (pad));
|
GST_STREAM_GET_LOCK (pad));
|
||||||
gst_pipeline_post_message (GST_ELEMENT_MANAGER (fakesink),
|
gst_element_post_message (GST_ELEMENT (fakesink),
|
||||||
gst_message_new_eos (GST_OBJECT (fakesink)));
|
gst_message_new_eos (GST_OBJECT (fakesink)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,7 @@ 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 GstFlowReturn gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer);
|
static gboolean gst_fakesrc_loop (GstPad * pad);
|
||||||
static void gst_fakesrc_loop (GstElement * element);
|
|
||||||
|
|
||||||
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
@ -471,13 +470,8 @@ gst_fakesrc_update_functions (GstFakeSrc * src)
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
|
||||||
if (src->loop_based) {
|
|
||||||
gst_pad_set_get_function (pad, NULL);
|
|
||||||
} else {
|
|
||||||
gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
gst_pad_set_activate_function (pad, gst_fakesrc_activate);
|
||||||
|
gst_pad_set_loop_function (pad, gst_fakesrc_loop);
|
||||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
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_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||||
|
@ -784,20 +778,16 @@ gst_fakesrc_create_buffer (GstFakeSrc * src)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static gboolean
|
||||||
gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
gboolean result = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
|
|
||||||
|
|
||||||
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_FAKESRC (src), GST_FLOW_ERROR);
|
|
||||||
|
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
if (src->need_flush) {
|
if (src->need_flush) {
|
||||||
src->need_flush = FALSE;
|
src->need_flush = FALSE;
|
||||||
|
@ -809,14 +799,14 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
if (src->rt_num_buffers > 0)
|
if (src->rt_num_buffers > 0)
|
||||||
|
@ -826,7 +816,7 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
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));
|
||||||
result = GST_FLOW_UNEXPECTED;
|
result = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +856,7 @@ gst_fakesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
|
|
||||||
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
src->bytes_sent += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
*buffer = buf;
|
gst_pad_push (pad, buf);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
@ -874,26 +864,24 @@ done:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* gst_fakesrc_loop:
|
* gst_fakesrc_loop:
|
||||||
* @element: the faksesrc to loop
|
* @element: the faksesrc to loop
|
||||||
*
|
*
|
||||||
* generate an empty buffer and push it to the next element.
|
* generate an empty buffer and push it to the next element.
|
||||||
*/
|
*/
|
||||||
static void
|
static gboolean
|
||||||
gst_fakesrc_loop (GstElement * element)
|
gst_fakesrc_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFakeSrc *src;
|
GstFakeSrc *src;
|
||||||
const GList *pads;
|
const GList *pads;
|
||||||
GstTask *task;
|
GstTask *task;
|
||||||
|
|
||||||
g_return_if_fail (element != NULL);
|
src = GST_FAKESRC (GST_PAD_PARENT (pad));
|
||||||
g_return_if_fail (GST_IS_FAKESRC (element));
|
|
||||||
|
|
||||||
src = GST_FAKESRC (element);
|
|
||||||
task = src->task;
|
task = src->task;
|
||||||
|
|
||||||
pads = element->pads;
|
pads = GST_ELEMENT (src)->pads;
|
||||||
|
|
||||||
while (pads) {
|
while (pads) {
|
||||||
GstPad *pad = GST_PAD (pads->data);
|
GstPad *pad = GST_PAD (pads->data);
|
||||||
|
@ -902,22 +890,21 @@ gst_fakesrc_loop (GstElement * element)
|
||||||
|
|
||||||
ret = gst_fakesrc_get (pad, &buffer);
|
ret = gst_fakesrc_get (pad, &buffer);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ret = gst_pad_push (pad, buffer);
|
ret = gst_pad_push (pad, buffer);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->eos) {
|
if (src->eos) {
|
||||||
gst_task_stop (task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pads = g_list_next (pads);
|
pads = g_list_next (pads);
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_fakesrc_activate (GstPad * pad, gboolean active)
|
gst_fakesrc_activate (GstPad * pad, gboolean active)
|
||||||
|
@ -929,11 +916,11 @@ gst_fakesrc_activate (GstPad * pad, gboolean active)
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
if (GST_ELEMENT_MANAGER (fakesrc)) {
|
if (GST_ELEMENT_SCHEDULER (fakesrc)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
fakesrc->task =
|
fakesrc->task =
|
||||||
gst_scheduler_create_task (GST_ELEMENT_MANAGER (fakesrc)->scheduler,
|
gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (fakesrc),
|
||||||
(GstTaskFunction) gst_fakesrc_loop, fakesrc);
|
(GstTaskFunction) gst_fakesrc_loop, pad);
|
||||||
|
|
||||||
gst_task_start (fakesrc->task);
|
gst_task_start (fakesrc->task);
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
|
@ -171,6 +171,8 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
static gboolean gst_filesrc_check_filesize (GstFileSrc * src);
|
static gboolean gst_filesrc_check_filesize (GstFileSrc * src);
|
||||||
static GstFlowReturn gst_filesrc_get (GstPad * pad, GstBuffer ** buffer);
|
static GstFlowReturn gst_filesrc_get (GstPad * pad, GstBuffer ** buffer);
|
||||||
|
static GstFlowReturn gst_filesrc_getrange (GstPad * pad, guint64 offset,
|
||||||
|
guint length, GstBuffer ** buffer);
|
||||||
static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event);
|
||||||
static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
||||||
GstFormat * format, gint64 * value);
|
GstFormat * format, gint64 * value);
|
||||||
|
@ -248,7 +250,7 @@ gst_filesrc_init (GstFileSrc * src)
|
||||||
src->srcpad =
|
src->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
||||||
"src");
|
"src");
|
||||||
gst_pad_set_get_function (src->srcpad, gst_filesrc_get);
|
gst_pad_set_getrange_function (src->srcpad, gst_filesrc_getrange);
|
||||||
gst_pad_set_activate_function (src->srcpad, gst_filesrc_activate);
|
gst_pad_set_activate_function (src->srcpad, gst_filesrc_activate);
|
||||||
gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event);
|
gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event);
|
||||||
gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask);
|
gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask);
|
||||||
|
@ -688,13 +690,27 @@ gst_filesrc_get_read (GstFileSrc * src)
|
||||||
return GST_DATA (buf);
|
return GST_DATA (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_filesrc_getrange (GstPad * pad, guint64 offset, guint length,
|
||||||
|
GstBuffer ** buffer)
|
||||||
|
{
|
||||||
|
GstFileSrc *src;
|
||||||
|
|
||||||
|
src = GST_FILESRC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
src->curoffset = offset;
|
||||||
|
src->block_size = length;
|
||||||
|
|
||||||
|
return gst_filesrc_get (pad, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_filesrc_get (GstPad * pad, GstBuffer ** buffer)
|
gst_filesrc_get (GstPad * pad, GstBuffer ** buffer)
|
||||||
{
|
{
|
||||||
GstFileSrc *src;
|
GstFileSrc *src;
|
||||||
GstData *data;
|
GstData *data;
|
||||||
|
|
||||||
src = GST_FILESRC (gst_pad_get_parent (pad));
|
src = GST_FILESRC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN),
|
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN),
|
||||||
GST_FLOW_WRONG_STATE);
|
GST_FLOW_WRONG_STATE);
|
||||||
|
@ -863,24 +879,25 @@ gst_filesrc_close_file (GstFileSrc * src)
|
||||||
GST_FLAG_UNSET (src, GST_FILESRC_OPEN);
|
GST_FLAG_UNSET (src, GST_FILESRC_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gst_filesrc_loop (GstElement * element)
|
gst_filesrc_loop (GstElement * element)
|
||||||
{
|
{
|
||||||
GstFileSrc *filesrc;
|
GstFileSrc *filesrc;
|
||||||
GstFlowReturn result;
|
gboolean result;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
filesrc = GST_FILESRC (element);
|
filesrc = GST_FILESRC (element);
|
||||||
|
|
||||||
result = gst_filesrc_get (filesrc->srcpad, &buffer);
|
result = gst_filesrc_get (filesrc->srcpad, &buffer);
|
||||||
if (result != GST_FLOW_OK) {
|
if (result != GST_FLOW_OK) {
|
||||||
gst_task_stop (filesrc->task);
|
return FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
result = gst_pad_push (filesrc->srcpad, buffer);
|
result = gst_pad_push (filesrc->srcpad, buffer);
|
||||||
if (result != GST_FLOW_OK) {
|
if (result != GST_FLOW_OK) {
|
||||||
gst_task_stop (filesrc->task);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,9 +125,9 @@ static void gst_queue_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_queue_get (GstPad * pad, GstBuffer ** buffer);
|
|
||||||
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
||||||
guint size, GstCaps * caps);
|
guint size, GstCaps * caps);
|
||||||
|
static gboolean gst_queue_loop (GstPad * pad);
|
||||||
|
|
||||||
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ gst_queue_init (GstQueue * queue)
|
||||||
queue->srcpad =
|
queue->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate),
|
||||||
"src");
|
"src");
|
||||||
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
|
gst_pad_set_loop_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_loop));
|
||||||
gst_pad_set_activate_function (queue->srcpad,
|
gst_pad_set_activate_function (queue->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_queue_src_activate));
|
GST_DEBUG_FUNCPTR (gst_queue_src_activate));
|
||||||
gst_pad_set_link_function (queue->srcpad,
|
gst_pad_set_link_function (queue->srcpad,
|
||||||
|
@ -433,8 +433,6 @@ gst_queue_locked_flush (GstQueue * queue)
|
||||||
while (!g_queue_is_empty (queue->queue)) {
|
while (!g_queue_is_empty (queue->queue)) {
|
||||||
GstData *data = g_queue_pop_head (queue->queue);
|
GstData *data = g_queue_pop_head (queue->queue);
|
||||||
|
|
||||||
/* First loose the reference we added when putting that data in the queue */
|
|
||||||
gst_data_unref (data);
|
|
||||||
/* Then loose another reference because we are supposed to destroy that
|
/* Then loose another reference because we are supposed to destroy that
|
||||||
data when flushing */
|
data when flushing */
|
||||||
gst_data_unref (data);
|
gst_data_unref (data);
|
||||||
|
@ -492,7 +490,6 @@ gst_queue_handle_sink_event (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_event_ref (event);
|
|
||||||
g_queue_push_tail (queue->queue, event);
|
g_queue_push_tail (queue->queue, event);
|
||||||
g_cond_signal (queue->item_add);
|
g_cond_signal (queue->item_add);
|
||||||
GST_QUEUE_MUTEX_UNLOCK;
|
GST_QUEUE_MUTEX_UNLOCK;
|
||||||
|
@ -621,11 +618,6 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put the buffer on the tail of the list. We keep a reference,
|
|
||||||
* so that the buffer is read-only while in here. There's a good
|
|
||||||
* reason to do so: we have a size and time counter, and any
|
|
||||||
* modification to the content could change any of the two. */
|
|
||||||
gst_buffer_ref (buffer);
|
|
||||||
g_queue_push_tail (queue->queue, buffer);
|
g_queue_push_tail (queue->queue, buffer);
|
||||||
|
|
||||||
/* add buffer to the statistics */
|
/* add buffer to the statistics */
|
||||||
|
@ -648,14 +640,14 @@ out_unref:
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static gboolean
|
||||||
gst_queue_get (GstPad * pad, GstBuffer ** buffer)
|
gst_queue_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstQueue *queue;
|
GstQueue *queue;
|
||||||
GstData *data;
|
GstData *data;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
gboolean result = TRUE;
|
||||||
|
|
||||||
queue = GST_QUEUE (gst_object_get_parent (GST_OBJECT (pad)));
|
queue = GST_QUEUE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
/* have to lock for thread-safety */
|
/* have to lock for thread-safety */
|
||||||
GST_QUEUE_MUTEX_LOCK;
|
GST_QUEUE_MUTEX_LOCK;
|
||||||
|
@ -696,23 +688,16 @@ restart:
|
||||||
if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE)
|
if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE)
|
||||||
queue->cur_level.time -= GST_BUFFER_DURATION (data);
|
queue->cur_level.time -= GST_BUFFER_DURATION (data);
|
||||||
|
|
||||||
*buffer = GST_BUFFER (data);
|
gst_pad_push (pad, GST_BUFFER (data));
|
||||||
} else {
|
} else {
|
||||||
if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
|
if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
|
||||||
result = GST_FLOW_WRONG_STATE;
|
result = FALSE;
|
||||||
}
|
}
|
||||||
gst_pad_push_event (queue->srcpad, GST_EVENT (data));
|
gst_pad_push_event (queue->srcpad, GST_EVENT (data));
|
||||||
if (result == GST_FLOW_OK)
|
if (result == TRUE)
|
||||||
goto restart;
|
goto restart;
|
||||||
else
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we're done, we can lose our own reference to
|
|
||||||
* the item, since we're no longer in danger. */
|
|
||||||
gst_data_unref (data);
|
|
||||||
|
|
||||||
done:
|
|
||||||
STATUS (queue, "after _get()");
|
STATUS (queue, "after _get()");
|
||||||
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del");
|
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del");
|
||||||
|
@ -784,37 +769,6 @@ gst_queue_handle_src_query (GstPad * pad,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_queue_loop (GstElement * element)
|
|
||||||
{
|
|
||||||
GstQueue *queue;
|
|
||||||
GstTask *task;
|
|
||||||
GstBuffer *buffer;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
g_return_if_fail (element != NULL);
|
|
||||||
g_return_if_fail (GST_IS_QUEUE (element));
|
|
||||||
|
|
||||||
queue = GST_QUEUE (element);
|
|
||||||
task = queue->task;
|
|
||||||
|
|
||||||
ret = gst_queue_get (queue->srcpad, &buffer);
|
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "stopping, get returned %d",
|
|
||||||
ret);
|
|
||||||
gst_task_stop (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ret = gst_pad_push (queue->srcpad, buffer);
|
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "stopping, push returned %d",
|
|
||||||
ret);
|
|
||||||
gst_task_stop (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_queue_src_activate (GstPad * pad, gboolean active)
|
gst_queue_src_activate (GstPad * pad, gboolean active)
|
||||||
{
|
{
|
||||||
|
@ -825,18 +779,18 @@ gst_queue_src_activate (GstPad * pad, gboolean active)
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* if we have a scheduler we can start the task */
|
/* if we have a scheduler we can start the task */
|
||||||
if (GST_ELEMENT_MANAGER (queue)) {
|
if (GST_ELEMENT_SCHEDULER (queue)) {
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
queue->task =
|
queue->task =
|
||||||
gst_scheduler_create_task (GST_ELEMENT_MANAGER (queue)->scheduler,
|
gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (queue),
|
||||||
(GstTaskFunction) gst_queue_loop, queue);
|
(GstTaskFunction) gst_queue_loop, pad);
|
||||||
|
|
||||||
gst_task_start (queue->task);
|
gst_task_start (queue->task);
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* step 1, unblock chain and get functions */
|
/* step 1, unblock chain and loop functions */
|
||||||
queue->interrupt = TRUE;
|
queue->interrupt = TRUE;
|
||||||
g_cond_signal (queue->item_add);
|
g_cond_signal (queue->item_add);
|
||||||
g_cond_signal (queue->item_del);
|
g_cond_signal (queue->item_del);
|
||||||
|
@ -865,8 +819,7 @@ gst_queue_change_state (GstElement * element)
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change");
|
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change");
|
||||||
|
|
||||||
/* lock the queue so another thread (not in sync with this thread's state)
|
/* lock the queue so another thread (not in sync with this thread's state)
|
||||||
* can't call this queue's _get (or whatever)
|
* can't call this queue's _loop (or whatever) */
|
||||||
*/
|
|
||||||
GST_QUEUE_MUTEX_LOCK;
|
GST_QUEUE_MUTEX_LOCK;
|
||||||
|
|
||||||
switch (GST_STATE_TRANSITION (element)) {
|
switch (GST_STATE_TRANSITION (element)) {
|
||||||
|
|
|
@ -627,9 +627,9 @@ print_pad_info (GstElement * element)
|
||||||
if (realpad->chainfunc)
|
if (realpad->chainfunc)
|
||||||
n_print (" Has chainfunc(): %s\n",
|
n_print (" Has chainfunc(): %s\n",
|
||||||
GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
|
GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
|
||||||
if (realpad->getfunc)
|
if (realpad->getrangefunc)
|
||||||
n_print (" Has getfunc(): %s\n",
|
n_print (" Has getrangefunc(): %s\n",
|
||||||
GST_DEBUG_FUNCPTR_NAME (realpad->getfunc));
|
GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc));
|
||||||
if (realpad->formatsfunc != gst_pad_get_formats_default) {
|
if (realpad->formatsfunc != gst_pad_get_formats_default) {
|
||||||
n_print (" Supports seeking/conversion/query formats:\n");
|
n_print (" Supports seeking/conversion/query formats:\n");
|
||||||
print_formats (gst_pad_get_formats (GST_PAD (realpad)));
|
print_formats (gst_pad_get_formats (GST_PAD (realpad)));
|
||||||
|
|
|
@ -471,7 +471,7 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
gst_bus_add_watch (GST_PIPELINE (pipeline)->bus,
|
gst_bus_add_watch (gst_element_get_bus (GST_ELEMENT (pipeline)),
|
||||||
(GstBusHandler) message_received, pipeline);
|
(GstBusHandler) message_received, pipeline);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -602,9 +602,9 @@ print_element_info (GstElementFactory * factory)
|
||||||
if (realpad->chainfunc)
|
if (realpad->chainfunc)
|
||||||
PUT_STRING (4, "<chain-based function=\"%s\"/>",
|
PUT_STRING (4, "<chain-based function=\"%s\"/>",
|
||||||
GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
|
GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
|
||||||
if (realpad->getfunc)
|
if (realpad->getrangefunc)
|
||||||
PUT_STRING (4, "<get-based function=\"%s\"/>",
|
PUT_STRING (4, "<get-range-based function=\"%s\"/>",
|
||||||
GST_DEBUG_FUNCPTR_NAME (realpad->getfunc));
|
GST_DEBUG_FUNCPTR_NAME (realpad->getrangefunc));
|
||||||
if (realpad->formatsfunc != gst_pad_get_formats_default) {
|
if (realpad->formatsfunc != gst_pad_get_formats_default) {
|
||||||
PUT_STRING (4, "<formats-function function=\"%s\">",
|
PUT_STRING (4, "<formats-function function=\"%s\">",
|
||||||
GST_DEBUG_FUNCPTR_NAME (realpad->formatsfunc));
|
GST_DEBUG_FUNCPTR_NAME (realpad->formatsfunc));
|
||||||
|
|
Loading…
Reference in a new issue