X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstpad.c;h=2a0069b6ebd72f7cef4cd941c9590f57493ec927;hb=2cab15c9f6370db5b068ee8c1dd9717655d6c3f5;hp=ad44d8388e657771e5cab981625df35e1d6de03b;hpb=8e6b5c7acf058908eae2bcb602ad6ab057db2e03;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstpad.c b/gst/gstpad.c index ad44d83..2a0069b 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1375,6 +1375,14 @@ gst_pad_mark_reconfigure (GstPad * pad) } /** + * gst_pad_set_activate_function: + * @p: a #GstPad. + * @f: the #GstPadActivateFunction to set. + * + * Calls gst_pad_set_activate_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_activate_function_full: * @pad: a #GstPad. * @activate: the #GstPadActivateFunction to set. @@ -1404,6 +1412,14 @@ gst_pad_set_activate_function_full (GstPad * pad, } /** + * gst_pad_set_activatemode_function: + * @p: a #GstPad. + * @f: the #GstPadActivateModeFunction to set. + * + * Calls gst_pad_set_activatemode_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_activatemode_function_full: * @pad: a #GstPad. * @activatemode: the #GstPadActivateModeFunction to set. @@ -1431,6 +1447,14 @@ gst_pad_set_activatemode_function_full (GstPad * pad, } /** + * gst_pad_set_chain_function: + * @p: a sink #GstPad. + * @f: the #GstPadChainFunction to set. + * + * Calls gst_pad_set_chain_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_chain_function_full: * @pad: a sink #GstPad. * @chain: the #GstPadChainFunction to set. @@ -1458,6 +1482,14 @@ gst_pad_set_chain_function_full (GstPad * pad, GstPadChainFunction chain, } /** + * gst_pad_set_chain_list_function: + * @p: a sink #GstPad. + * @f: the #GstPadChainListFunction to set. + * + * Calls gst_pad_set_chain_list_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_chain_list_function_full: * @pad: a sink #GstPad. * @chainlist: the #GstPadChainListFunction to set. @@ -1489,6 +1521,14 @@ gst_pad_set_chain_list_function_full (GstPad * pad, } /** + * gst_pad_set_getrange_function: + * @p: a source #GstPad. + * @f: the #GstPadGetRangeFunction to set. + * + * Calls gst_pad_set_getrange_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_getrange_function_full: * @pad: a source #GstPad. * @get: the #GstPadGetRangeFunction to set. @@ -1517,6 +1557,14 @@ gst_pad_set_getrange_function_full (GstPad * pad, GstPadGetRangeFunction get, } /** + * gst_pad_set_event_function: + * @p: a #GstPad of either direction. + * @f: the #GstPadEventFunction to set. + * + * Calls gst_pad_set_event_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_event_function_full: * @pad: a #GstPad of either direction. * @event: the #GstPadEventFunction to set. @@ -1542,6 +1590,14 @@ gst_pad_set_event_function_full (GstPad * pad, GstPadEventFunction event, } /** + * gst_pad_set_query_function: + * @p: a #GstPad of either direction. + * @f: the #GstPadQueryFunction to set. + * + * Calls gst_pad_set_query_function_full() with NULL for the user_data and + * notify. + */ +/** * gst_pad_set_query_function_full: * @pad: a #GstPad of either direction. * @query: the #GstPadQueryFunction to set. @@ -1567,6 +1623,14 @@ gst_pad_set_query_function_full (GstPad * pad, GstPadQueryFunction query, } /** + * gst_pad_set_iterate_internal_links_function: + * @p: a #GstPad of either direction. + * @f: the #GstPadIterIntLinkFunction to set. + * + * Calls gst_pad_set_iterate_internal_links_function_full() with NULL + * for the user_data and notify. + */ +/** * gst_pad_set_iterate_internal_links_function_full: * @pad: a #GstPad of either direction. * @iterintlink: the #GstPadIterIntLinkFunction to set. @@ -1595,6 +1659,14 @@ gst_pad_set_iterate_internal_links_function_full (GstPad * pad, } /** + * gst_pad_set_link_function: + * @p: a #GstPad. + * @f: the #GstPadLinkFunction to set. + * + * Calls gst_pad_set_link_function_full() with NULL + * for the user_data and notify. + */ +/** * gst_pad_set_link_function_full: * @pad: a #GstPad. * @link: the #GstPadLinkFunction to set. @@ -1630,6 +1702,14 @@ gst_pad_set_link_function_full (GstPad * pad, GstPadLinkFunction link, } /** + * gst_pad_set_unlink_function: + * @p: a #GstPad. + * @f: the #GstPadUnlinkFunction to set. + * + * Calls gst_pad_set_unlink_function_full() with NULL + * for the user_data and notify. + */ +/** * gst_pad_set_unlink_function_full: * @pad: a #GstPad. * @unlink: the #GstPadUnlinkFunction to set. @@ -2637,12 +2717,6 @@ gst_pad_event_default (GstPad * pad, GstObject * parent, GstEvent * event) GST_LOG_OBJECT (pad, "default event handler"); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - GST_DEBUG_OBJECT (pad, "pausing task because of eos"); - gst_pad_pause_task (pad); - break; - } case GST_EVENT_CAPS: forward = GST_PAD_IS_PROXY_CAPS (pad); result = TRUE; @@ -3185,9 +3259,10 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data) break; case GST_FLOW_NOT_LINKED: /* not linked is not a problem, we are sticky so the event will be - * sent later */ + * sent later but only for non-EOS events */ GST_DEBUG_OBJECT (pad, "pad was not linked"); - data->ret = GST_FLOW_OK; + if (GST_EVENT_TYPE (event) != GST_EVENT_EOS) + data->ret = GST_FLOW_OK; /* fallthrough */ default: GST_DEBUG_OBJECT (pad, "mark pending events"); @@ -3222,22 +3297,11 @@ check_sticky (GstPad * pad) * event failed. */ if (data.ret != GST_FLOW_OK && !data.was_eos) { - GArray *events = pad->priv->events; - gint i, len; - - len = events->len; - for (i = 0; i < len; i++) { - PadEvent *ev = &g_array_index (events, PadEvent, i); + PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0); - if (G_UNLIKELY (ev->event == NULL) || ev->received) - continue; - - if (GST_EVENT_TYPE (ev->event) == GST_EVENT_EOS) { - gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event), - GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM); - - break; - } + if (ev && !ev->received) { + data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event), + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM); } } } @@ -3514,6 +3578,9 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data) if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; + if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH)) goto wrong_mode; @@ -3575,6 +3642,14 @@ flushing: gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); return GST_FLOW_FLUSHING; } +eos: + { + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS"); + GST_OBJECT_UNLOCK (pad); + GST_PAD_STREAM_UNLOCK (pad); + gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); + return GST_FLOW_EOS; + } wrong_mode: { g_critical ("chain on pad %s:%s but it was not in push mode", @@ -3723,6 +3798,9 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data) if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; + if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH)) goto wrong_mode; @@ -3768,6 +3846,13 @@ flushing: gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); return GST_FLOW_FLUSHING; } +eos: + { + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS"); + GST_OBJECT_UNLOCK (pad); + gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); + return GST_FLOW_EOS; + } wrong_mode: { g_critical ("pushing on pad %s:%s but it was not activated in push mode", @@ -4330,6 +4415,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event, /* Remove sticky EOS events */ GST_LOG_OBJECT (pad, "Removing pending EOS events"); remove_event_by_type (pad, GST_EVENT_EOS); + GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH; break; @@ -4338,6 +4424,11 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event, if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushed; + /* No need to check for EOS here as either the caller (gst_pad_push_event()) + * checked already or this is called as part of pushing sticky events, + * in which case we still want to forward the EOS event downstream. + */ + switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: /* pass the adjusted segment event on. We need to do this even if @@ -4419,6 +4510,11 @@ not_linked: GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked"); GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS); gst_event_unref (event); + + /* unlinked pads should not influence latency configuration */ + if (event_type == GST_EVENT_LATENCY) + return GST_FLOW_OK; + return GST_FLOW_NOT_LINKED; } idle_probe_stopped: @@ -4447,7 +4543,7 @@ idle_probe_stopped: gboolean gst_pad_push_event (GstPad * pad, GstEvent * event) { - gboolean res; + gboolean res = FALSE; GstPadProbeType type; gboolean sticky, serialized; @@ -4475,12 +4571,17 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushed; + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; + /* srcpad sticky events are store immediately, the received flag is set * to FALSE and will be set to TRUE when we can successfully push the * event to the peer pad */ if (gst_pad_store_sticky_event (pad, event, TRUE)) { GST_DEBUG_OBJECT (pad, "event %s updated", GST_EVENT_TYPE_NAME (event)); } + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) + GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS); } if (GST_PAD_IS_SRC (pad) && (serialized || sticky)) { /* all serialized or sticky events on the srcpad trigger push of @@ -4491,8 +4592,14 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) /* other events are pushed right away */ res = (gst_pad_push_event_unchecked (pad, event, type) == GST_FLOW_OK); } else { + /* Errors in sticky event pushing are no problem and ignored here + * as they will cause more meaningful errors during data flow. + * For EOS events, that are not followed by data flow, we still + * return FALSE here though. + */ + if (GST_EVENT_TYPE (event) != GST_EVENT_EOS) + res = TRUE; gst_event_unref (event); - res = TRUE; } GST_OBJECT_UNLOCK (pad); @@ -4519,13 +4626,20 @@ flushed: gst_event_unref (event); return FALSE; } +eos: + { + GST_DEBUG_OBJECT (pad, "We're EOS"); + GST_OBJECT_UNLOCK (pad); + gst_event_unref (event); + return FALSE; + } } /* Check if we can call the event function with the given event */ static GstFlowReturn pre_eventfunc_check (GstPad * pad, GstEvent * event) { - GstCaps *caps, *templ; + GstCaps *caps; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: @@ -4533,12 +4647,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event) /* backwards compatibility mode for caps */ gst_event_parse_caps (event, &caps); - /* See if pad accepts the caps */ - templ = gst_pad_get_pad_template_caps (pad); - if (!gst_caps_is_subset (caps, templ)) + if (!gst_pad_query_accept_caps (pad, caps)) goto not_accepted; - - gst_caps_unref (templ); break; } default: @@ -4549,11 +4659,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event) /* ERRORS */ not_accepted: { - gst_caps_unref (templ); GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "caps %" GST_PTR_FORMAT " not accepted", caps); - GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, - "no intersection with template %" GST_PTR_FORMAT, templ); return GST_FLOW_NOT_NEGOTIATED; } } @@ -4595,6 +4702,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, /* Remove pending EOS events */ GST_LOG_OBJECT (pad, "Removing pending EOS events"); remove_event_by_type (pad, GST_EVENT_EOS); + GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS); GST_OBJECT_UNLOCK (pad); /* grab stream lock */ @@ -4615,6 +4723,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, goto flushing; if (serialized) { + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; + /* lock order: STREAM_LOCK, LOCK, recheck flushing. */ GST_OBJECT_UNLOCK (pad); GST_PAD_STREAM_LOCK (pad); @@ -4622,6 +4733,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, GST_OBJECT_LOCK (pad); if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; + + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; } switch (GST_EVENT_TYPE (event)) { @@ -4676,6 +4790,8 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, /* after the event function accepted the event, we can store the sticky * event on the pad */ gst_pad_store_sticky_event (pad, event, FALSE); + if (event_type == GST_EVENT_EOS) + GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS); } gst_event_unref (event); } @@ -4696,6 +4812,16 @@ flushing: gst_event_unref (event); return GST_FLOW_FLUSHING; } +eos: + { + GST_OBJECT_UNLOCK (pad); + if (need_unlock) + GST_PAD_STREAM_UNLOCK (pad); + GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad, + "Received event on EOS pad. Discarding"); + gst_event_unref (event); + return GST_FLOW_EOS; + } probe_stopped: { GST_OBJECT_UNLOCK (pad);