mpeg4videoparse: Set srcpad caps before forwarding newsegment

This holds all newsegement and most other events till there is enough
data to set srcpad caps, so that the downstream link is properly
negotiated before data starts flowing.

https://bugzilla.gnome.org/show_bug.cgi?id=635204
This commit is contained in:
Arun Raghavan 2010-11-18 13:39:23 +05:30 committed by Edward Hervey
parent 8f30fca636
commit 5b442d0712
2 changed files with 58 additions and 1 deletions

View file

@ -118,6 +118,22 @@ gst_mpeg4vparse_set_new_caps (GstMpeg4VParse * parse,
res = gst_pad_set_caps (parse->srcpad, out_caps);
gst_caps_unref (out_caps);
parse->have_src_caps = TRUE;
if (parse->pending_segment != NULL) {
/* We can send pending events since we now have caps for the srcpad */
gst_pad_push_event (parse->srcpad, parse->pending_segment);
parse->pending_segment = NULL;
if (G_UNLIKELY (parse->pending_events != NULL)) {
GList *l;
for (l = parse->pending_events; l != NULL; l = l->next)
gst_pad_push_event (parse->srcpad, GST_EVENT (l->data));
g_list_free (parse->pending_events);
parse->pending_events = NULL;
}
}
return res;
}
@ -794,6 +810,11 @@ gst_mpeg4vparse_sink_event (GstPad * pad, GstEvent * event)
parse->offset = 0;
break;
case GST_EVENT_EOS:
if (parse->pending_segment != NULL) {
/* Send pending newsegment before EOS */
gst_pad_push_event (parse->srcpad, parse->pending_segment);
parse->pending_segment = NULL;
}
if (parse->state == PARSE_VOP_FOUND) {
/* If we've found the start of the VOP assume what's left in the
* adapter is the complete VOP. This might cause us to send an
@ -802,11 +823,25 @@ gst_mpeg4vparse_sink_event (GstPad * pad, GstEvent * event)
gst_mpeg4vparse_push (parse, gst_adapter_available (parse->adapter));
}
/* fallthrough */
case GST_EVENT_FLUSH_START:
res = gst_pad_event_default (pad, event);
break;
case GST_EVENT_NEWSEGMENT:
gst_event_replace (&parse->pending_segment, event);
gst_event_unref (event);
res = TRUE;
break;
default:
if (G_UNLIKELY (!parse->have_src_caps || parse->pending_segment)) {
/* We don't yet have enough data to set caps on the srcpad, so collect
* non-critical events till we do */
parse->pending_events = g_list_append (parse->pending_events, event);
res = TRUE;
} else
res = gst_pad_event_default (pad, event);
break;
}
res = gst_pad_event_default (pad, event);
gst_object_unref (parse);
return res;
@ -879,6 +914,16 @@ gst_mpeg4vparse_cleanup (GstMpeg4VParse * parse)
parse->config = NULL;
}
if (parse->pending_segment)
gst_event_unref (parse->pending_segment);
parse->pending_segment = NULL;
g_list_foreach (parse->pending_events, (GFunc) gst_event_unref, NULL);
g_list_free (parse->pending_events);
parse->pending_events = NULL;
parse->have_src_caps = FALSE;
parse->state = PARSE_NEED_START;
parse->have_config = FALSE;
parse->offset = 0;
@ -918,6 +963,14 @@ gst_mpeg4vparse_dispose (GObject * object)
parse->config = NULL;
}
if (parse->pending_segment)
gst_event_unref (parse->pending_segment);
parse->pending_segment = NULL;
g_list_foreach (parse->pending_events, (GFunc) gst_event_unref, NULL);
g_list_free (parse->pending_events);
parse->pending_events = NULL;
GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}

View file

@ -73,6 +73,10 @@ struct _GstMpeg4VParse {
GstClockTime frame_duration;
gboolean drop;
gboolean have_src_caps;
GstEvent *pending_segment;
GList *pending_events;
};
struct _GstMpeg4VParseClass {