mpegtsparse: Don't use GstIterator, do change detection ourselves.

Using a GstIterator is slow because we have to create/destroy that
iterator every single time.
We just do the threadsafe cookie check and list iteration ourselves.
This commit is contained in:
Edward Hervey 2009-09-16 20:39:52 +02:00
parent c224da54e4
commit 314e2dabd5

View file

@ -766,14 +766,15 @@ static GstFlowReturn
mpegts_parse_push (MpegTSParse * parse, MpegTSPacketizerPacket * packet,
MpegTSPacketizerSection * section)
{
GstIterator *iterator;
guint32 pads_cookie;
gboolean done = FALSE;
gpointer pad = NULL;
GstPad *pad = NULL;
MpegTSParsePad *tspad;
guint16 pid;
GstBuffer *buffer;
GstFlowReturn ret;
GstCaps *caps;
GList *srcpads;
pid = packet->pid;
buffer = packet->buffer;
@ -790,54 +791,67 @@ mpegts_parse_push (MpegTSParse * parse, MpegTSPacketizerPacket * packet,
ret = GST_FLOW_NOT_LINKED;
else
ret = GST_FLOW_OK;
/* Get cookie and source pads list */
pads_cookie = GST_ELEMENT_CAST (parse)->pads_cookie;
srcpads = GST_ELEMENT_CAST (parse)->srcpads;
if (G_LIKELY (srcpads)) {
pad = GST_PAD_CAST (srcpads->data);
g_object_ref (pad);
}
GST_OBJECT_UNLOCK (parse);
iterator = gst_element_iterate_src_pads (GST_ELEMENT_CAST (parse));
while (!done) {
switch (gst_iterator_next (iterator, &pad)) {
case GST_ITERATOR_OK:
tspad = gst_pad_get_element_private (GST_PAD_CAST (pad));
while (pad && !done) {
tspad = gst_pad_get_element_private (pad);
/* make sure to push only once if the iterator resyncs */
if (!tspad->pushed) {
/* ref the buffer as gst_pad_push takes a ref but we want to reuse the
* same buffer for next pushes */
gst_buffer_ref (buffer);
if (section) {
tspad->flow_return =
mpegts_parse_tspad_push_section (parse, tspad, section, buffer);
} else {
tspad->flow_return =
mpegts_parse_tspad_push (parse, tspad, pid, buffer);
}
tspad->pushed = TRUE;
if (G_LIKELY (!tspad->pushed)) {
/* ref the buffer as gst_pad_push takes a ref but we want to reuse the
* same buffer for next pushes */
gst_buffer_ref (buffer);
if (section) {
tspad->flow_return =
mpegts_parse_tspad_push_section (parse, tspad, section, buffer);
} else {
tspad->flow_return =
mpegts_parse_tspad_push (parse, tspad, pid, buffer);
}
tspad->pushed = TRUE;
if (G_UNLIKELY (GST_FLOW_IS_FATAL (tspad->flow_return))) {
/* return the error upstream */
ret = tspad->flow_return;
done = TRUE;
}
}
if (ret == GST_FLOW_NOT_LINKED)
ret = tspad->flow_return;
/* the iterator refs the pad */
g_object_unref (GST_PAD_CAST (pad));
break;
case GST_ITERATOR_RESYNC:
gst_iterator_resync (iterator);
break;
case GST_ITERATOR_DONE:
if (G_UNLIKELY (GST_FLOW_IS_FATAL (tspad->flow_return))) {
/* return the error upstream */
ret = tspad->flow_return;
done = TRUE;
break;
default:
g_warning ("this should not be reached");
}
}
if (ret == GST_FLOW_NOT_LINKED)
ret = tspad->flow_return;
g_object_unref (pad);
if (G_UNLIKELY (!done)) {
GST_OBJECT_LOCK (parse);
if (G_UNLIKELY (pads_cookie != GST_ELEMENT_CAST (parse)->pads_cookie)) {
/* resync */
GST_DEBUG ("resync");
pads_cookie = GST_ELEMENT_CAST (parse)->pads_cookie;
srcpads = GST_ELEMENT_CAST (parse)->srcpads;
} else {
GST_DEBUG ("getting next pad");
/* Get next pad */
srcpads = g_list_next (srcpads);
}
if (srcpads) {
pad = GST_PAD_CAST (srcpads->data);
g_object_ref (pad);
} else
done = TRUE;
GST_OBJECT_UNLOCK (parse);
}
}
gst_iterator_free (iterator);
gst_buffer_unref (buffer);
packet->buffer = NULL;