X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstpad.c;h=dcd52f2ff15f1eec75ae8461e47bdf79612ab562;hb=cc6342d853f4252c5d5cf09fff9d3379ad467fbc;hp=5007c4c0eccbd493b5264aa9131624cd4a61bfd1;hpb=2db8e3705fba5baf51c33baaeb16dd285c992fae;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstpad.c b/gst/gstpad.c index 5007c4c..dcd52f2 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -169,7 +169,7 @@ typedef struct gboolean handled; gboolean marshalled; - GHook **called_probes; + gulong *called_probes; guint n_called_probes; guint called_probes_size; gboolean retry; @@ -190,7 +190,7 @@ static GstFlowReturn gst_pad_chain_list_default (GstPad * pad, static GstFlowReturn gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, GstPadProbeType type); static GstFlowReturn gst_pad_push_event_unchecked (GstPad * pad, - GstEvent ** event, GstPadProbeType type); + GstEvent * event, GstPadProbeType type); static gboolean activate_mode_internal (GstPad * pad, GstObject * parent, GstPadMode mode, gboolean active); @@ -644,13 +644,13 @@ restart: /* should be called with LOCK */ static GstEvent * -_apply_pad_offset (GstPad * pad, GstEvent * event, gint64 applied_offset, - gboolean upstream) +_apply_pad_offset (GstPad * pad, GstEvent * event, gboolean upstream, + gint64 pad_offset) { gint64 offset; GST_DEBUG_OBJECT (pad, "apply pad offset %" GST_STIME_FORMAT, - GST_STIME_ARGS (pad->offset)); + GST_STIME_ARGS (pad_offset)); if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) { GstSegment segment; @@ -661,16 +661,16 @@ _apply_pad_offset (GstPad * pad, GstEvent * event, gint64 applied_offset, gst_event_copy_segment (event, &segment); gst_event_unref (event); - gst_segment_offset_running_time (&segment, segment.format, applied_offset); + gst_segment_offset_running_time (&segment, segment.format, pad_offset); event = gst_event_new_segment (&segment); } event = gst_event_make_writable (event); offset = gst_event_get_running_time_offset (event); if (upstream) - offset -= applied_offset; + offset -= pad_offset; else - offset += applied_offset; + offset += pad_offset; gst_event_set_running_time_offset (event, offset); return event; @@ -680,11 +680,10 @@ static inline GstEvent * apply_pad_offset (GstPad * pad, GstEvent * event, gboolean upstream) { if (G_UNLIKELY (pad->offset != 0)) - return _apply_pad_offset (pad, event, pad->offset, upstream); + return _apply_pad_offset (pad, event, upstream, pad->offset); return event; } - /* should be called with the OBJECT_LOCK */ static GstCaps * get_pad_caps (GstPad * pad) @@ -833,8 +832,7 @@ gst_pad_get_property (GObject * object, guint prop_id, * will be assigned. * This function makes a copy of the name so you can safely free the name. * - * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in - * case of an error. + * Returns: (transfer floating): a new #GstPad. * * MT safe. */ @@ -855,8 +853,7 @@ gst_pad_new (const gchar * name, GstPadDirection direction) * will be assigned. * This function makes a copy of the name so you can safely free the name. * - * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in - * case of an error. + * Returns: (transfer floating): a new #GstPad. */ GstPad * gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name) @@ -881,8 +878,7 @@ gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name) * will be assigned. * This function makes a copy of the name so you can safely free the name. * - * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in - * case of an error. + * Returns: (transfer floating): a new #GstPad. */ GstPad * gst_pad_new_from_static_template (GstStaticPadTemplate * templ, @@ -1373,6 +1369,9 @@ cleanup_hook (GstPad * pad, GHook * hook) { GstPadProbeType type; + GST_DEBUG_OBJECT (pad, + "cleaning up hook %lu with flags %08x", hook->hook_id, hook->flags); + if (!G_HOOK_IS_VALID (hook)) return; @@ -2083,6 +2082,10 @@ gst_pad_set_link_function_full (GstPad * pad, GstPadLinkFunction link, * * Sets the given unlink function for the pad. It will be called * when the pad is unlinked. + * + * Note that the pad's lock is already held when the unlink + * function is called, so most pad functions cannot be called + * from within the callback. */ void gst_pad_set_unlink_function_full (GstPad * pad, GstPadUnlinkFunction unlink, @@ -3243,7 +3246,6 @@ done: /* Default latency implementation */ typedef struct { - guint count; gboolean live; GstClockTime min, max; } LatencyFoldData; @@ -3275,8 +3277,7 @@ query_latency_default_fold (const GValue * item, GValue * ret, GST_LOG_OBJECT (pad, "got latency live:%s min:%" G_GINT64_FORMAT " max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max); - /* FIXME : Why do we only take values into account if it's live ? */ - if (live || fold_data->count == 0) { + if (live) { if (min > fold_data->min) fold_data->min = min; @@ -3285,9 +3286,8 @@ query_latency_default_fold (const GValue * item, GValue * ret, else if (max < fold_data->max) fold_data->max = max; - fold_data->live = live; + fold_data->live = TRUE; } - fold_data->count += 1; } else if (peer) { GST_DEBUG_OBJECT (pad, "latency query failed"); g_value_set_boolean (ret, FALSE); @@ -3318,7 +3318,6 @@ gst_pad_query_latency_default (GstPad * pad, GstQuery * query) g_value_init (&ret, G_TYPE_BOOLEAN); retry: - fold_data.count = 0; fold_data.live = FALSE; fold_data.min = 0; fold_data.max = GST_CLOCK_TIME_NONE; @@ -3420,6 +3419,10 @@ gst_pad_query_default (GstPad * pad, GstObject * parent, GstQuery * query) ret = gst_pad_query_latency_default (pad, query); forward = FALSE; break; + case GST_QUERY_BITRATE: + /* FIXME: better default handling */ + forward = TRUE; + break; case GST_QUERY_POSITION: case GST_QUERY_SEEKING: case GST_QUERY_FORMATS: @@ -3473,7 +3476,7 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data) * if we're actually calling probes a second time */ if (data->retry) { for (i = 0; i < data->n_called_probes; i++) { - if (data->called_probes[i] == hook) { + if (data->called_probes[i] == hook->hook_id) { GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "hook %lu already called", hook->hook_id); return; @@ -3486,17 +3489,17 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data) if (data->called_probes_size > N_STACK_ALLOCATE_PROBES) { data->called_probes_size *= 2; data->called_probes = - g_renew (GHook *, data->called_probes, data->called_probes_size); + g_renew (gulong, data->called_probes, data->called_probes_size); } else { - GHook **tmp = data->called_probes; + gulong *tmp = data->called_probes; data->called_probes_size *= 2; - data->called_probes = g_new (GHook *, data->called_probes_size); + data->called_probes = g_new (gulong, data->called_probes_size); memcpy (data->called_probes, tmp, - N_STACK_ALLOCATE_PROBES * sizeof (GHook *)); + N_STACK_ALLOCATE_PROBES * sizeof (gulong)); } } - data->called_probes[data->n_called_probes++] = hook; + data->called_probes[data->n_called_probes++] = hook->hook_id; flags = hook->flags >> G_HOOK_FLAG_USER_SHIFT; type = info->type; @@ -3554,13 +3557,20 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data) info->id = hook->hook_id; + if ((flags & GST_PAD_PROBE_TYPE_IDLE)) + pad->priv->idle_running++; + GST_OBJECT_UNLOCK (pad); ret = callback (pad, info, hook->data); GST_OBJECT_LOCK (pad); - if (original_data != NULL && info->data == NULL) { + if ((flags & GST_PAD_PROBE_TYPE_IDLE)) + pad->priv->idle_running--; + + if (ret != GST_PAD_PROBE_HANDLED && original_data != NULL + && info->data == NULL) { GST_DEBUG_OBJECT (pad, "data item in pad probe info was dropped"); info->type = GST_PAD_PROBE_TYPE_INVALID; data->dropped = TRUE; @@ -3686,7 +3696,7 @@ do_probe_callbacks (GstPad * pad, GstPadProbeInfo * info, ProbeMarshall data; guint cookie; gboolean is_block; - GHook *called_probes[N_STACK_ALLOCATE_PROBES]; + gulong called_probes[N_STACK_ALLOCATE_PROBES]; data.pad = pad; data.info = info; @@ -3841,16 +3851,9 @@ gst_pad_get_offset (GstPad * pad) return result; } -/* This function will make sure that previously set offset is - * reverted as otherwise we would end up applying the new offset - * on top of the previously set one, which is not what we want. - * The event is also marked as not received. */ static gboolean -reschedule_event (GstPad * pad, PadEvent * ev, gint64 * prev_offset) +mark_event_not_received (GstPad * pad, PadEvent * ev, gpointer user_data) { - if (*prev_offset != 0) - ev->event = _apply_pad_offset (pad, ev->event, -*prev_offset, FALSE); - ev->received = FALSE; return TRUE; } @@ -3865,7 +3868,6 @@ reschedule_event (GstPad * pad, PadEvent * ev, gint64 * prev_offset) void gst_pad_set_offset (GstPad * pad, gint64 offset) { - gint64 prev_offset; g_return_if_fail (GST_IS_PAD (pad)); GST_OBJECT_LOCK (pad); @@ -3873,16 +3875,14 @@ gst_pad_set_offset (GstPad * pad, gint64 offset) if (pad->offset == offset) goto done; - prev_offset = pad->offset; pad->offset = offset; GST_DEBUG_OBJECT (pad, "changed offset to %" GST_STIME_FORMAT, GST_STIME_ARGS (offset)); /* resend all sticky events with updated offset on next buffer push */ - events_foreach (pad, (PadEventFunction) reschedule_event, &prev_offset); + events_foreach (pad, mark_event_not_received, NULL); GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS); - done: GST_OBJECT_UNLOCK (pad); } @@ -3924,10 +3924,8 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data) GST_EVENT_TYPE (data->event) < GST_EVENT_TYPE (event)) { data->ret = GST_FLOW_CUSTOM_SUCCESS_1; } else { - gst_event_ref (event); - data->ret = gst_pad_push_event_unchecked (pad, &event, + data->ret = gst_pad_push_event_unchecked (pad, gst_event_ref (event), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM); - gst_event_replace (&ev->event, event); if (data->ret == GST_FLOW_CUSTOM_SUCCESS_1) data->ret = GST_FLOW_OK; } @@ -3998,8 +3996,7 @@ check_sticky (GstPad * pad, GstEvent * event) PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0); if (ev && !ev->received) { - gst_event_ref (ev->event); - data.ret = gst_pad_push_event_unchecked (pad, &ev->event, + data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM); /* the event could have been dropped. Because this can only * happen if the user asked for it, it's not an error */ @@ -5301,13 +5298,13 @@ sticky_changed (GstPad * pad, PadEvent * ev, gpointer user_data) /* should be called with pad LOCK */ static GstFlowReturn -gst_pad_push_event_unchecked (GstPad * pad, GstEvent ** in_event, +gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event, GstPadProbeType type) { GstFlowReturn ret; GstPad *peerpad; GstEventType event_type; - GstEvent *event = *in_event; + gint64 old_pad_offset = pad->offset; /* pass the adjusted event on. We need to do this even if * there is no peer pad because of the probes. */ @@ -5390,6 +5387,15 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent ** in_event, events_foreach (pad, sticky_changed, &data); } + /* the pad offset might've been changed by any of the probes above. It + * would've been taken into account when repushing any of the sticky events + * above but not for our current event here */ + if (G_UNLIKELY (old_pad_offset != pad->offset)) { + event = + _apply_pad_offset (pad, event, GST_PAD_IS_SINK (pad), + pad->offset - old_pad_offset); + } + /* now check the peer pad */ peerpad = GST_PAD_PEER (pad); if (peerpad == NULL) @@ -5419,9 +5425,6 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent ** in_event, PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE, idle_probe_stopped, ret); } - - *in_event = event; - return ret; /* ERROR handling */ @@ -5542,7 +5545,7 @@ gst_pad_push_event (GstPad * pad, GstEvent * event) GstFlowReturn ret; /* other events are pushed right away */ - ret = gst_pad_push_event_unchecked (pad, &event, type); + ret = gst_pad_push_event_unchecked (pad, event, type); /* dropped events by a probe are not an error */ res = (ret == GST_FLOW_OK || ret == GST_FLOW_CUSTOM_SUCCESS || ret == GST_FLOW_CUSTOM_SUCCESS_1); @@ -5634,9 +5637,11 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, GstPadEventFunction eventfunc; GstPadEventFullFunction eventfullfunc = NULL; GstObject *parent; + gint64 old_pad_offset; GST_OBJECT_LOCK (pad); + old_pad_offset = pad->offset; event = apply_pad_offset (pad, event, GST_PAD_IS_SRC (pad)); if (GST_PAD_IS_SINK (pad)) @@ -5732,6 +5737,15 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event, PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH, event, probe_stopped); + /* the pad offset might've been changed by any of the probes above. It + * would've been taken into account when repushing any of the sticky events + * above but not for our current event here */ + if (G_UNLIKELY (old_pad_offset != pad->offset)) { + event = + _apply_pad_offset (pad, event, GST_PAD_IS_SRC (pad), + pad->offset - old_pad_offset); + } + eventfullfunc = GST_PAD_EVENTFULLFUNC (pad); eventfunc = GST_PAD_EVENTFUNC (pad); if (G_UNLIKELY (eventfunc == NULL && eventfullfunc == NULL))