diff -r d591b81268b0 -r 60033c7d3bab gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c --- a/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c Fri Dec 01 21:19:03 2006 +0000 +++ b/gst-plugins-nuvdemux/nuvdemux/gstnuvdemux.c Sat Dec 02 04:23:43 2006 +0000 @@ -264,6 +264,8 @@ static void gst_nuv_demux_update_duration (GstNuvDemux *nuv, guint64 current_timestamp); static gint64 gst_nuv_demux_get_bytes_duration (GstNuvDemux *nuv); static gint64 gst_nuv_demux_get_time_duration (GstNuvDemux *nuv); +GstBuffer * gst_nuv_demux_adapter_take_buffer (GstAdapter * adapter, guint nbytes); + GST_BOILERPLATE (GstNuvDemux, gst_nuv_demux, GstElement, GST_TYPE_ELEMENT); @@ -1056,12 +1058,7 @@ return GST_FLOW_ERROR_NO_DATA; if (move) { - guint8 *data = NULL; - data = (guint8 *) gst_adapter_take (nuv->priv->adapter, size); - *buffer = gst_buffer_new_alloc (size); - memcpy (GST_BUFFER_DATA (*buffer), data, size); - GST_BUFFER_MALLOCDATA (*buffer) = GST_BUFFER_DATA (*buffer); - g_free (data); + *buffer = gst_nuv_demux_adapter_take_buffer (nuv->priv->adapter, size); } else { guint8 *data = NULL; data = (guint8 *) gst_adapter_peek (nuv->priv->adapter, size); @@ -1078,15 +1075,12 @@ gboolean res = TRUE; GstNuvDemux *nuv = GST_NUV_DEMUX (gst_pad_get_parent (sinkpad)); - res = gst_pad_activate_push (sinkpad, TRUE); - /* - if (gst_pad_check_pull_range (sinkpad)) { res = gst_pad_activate_pull (sinkpad, TRUE); } else { res = gst_pad_activate_push (sinkpad, TRUE); } - */ + g_object_unref (nuv); return res; } @@ -1152,9 +1146,7 @@ gint64 stop; gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop); - GST_DEBUG_OBJECT (nuv, "got seek, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, cur, stop); - break; } case GST_EVENT_NEWSEGMENT: @@ -1186,7 +1178,6 @@ else nuv->time_qos = -1; */ - break; } @@ -1358,6 +1349,48 @@ return nuv->priv->duration_time; } +GstBuffer * +gst_nuv_demux_adapter_take_buffer (GstAdapter * adapter, guint nbytes) +{ + GstBuffer *buffer; + GstBuffer *cur; + guint8 *data; + + g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL); + g_return_val_if_fail (nbytes > 0, NULL); + + GST_LOG_OBJECT (adapter, "taking buffer of %u bytes", nbytes); + + /* we don't have enough data, return NULL. This is unlikely + * as one usually does an _available() first instead of peeking a + * random size. */ + if (G_UNLIKELY (nbytes > adapter->size)) + return NULL; + + /* our head buffer has enough data left, return it */ + cur = adapter->buflist->data; + if (GST_BUFFER_SIZE (cur) >= nbytes + adapter->skip) { + GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer", + nbytes); + buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes); + + gst_adapter_flush (adapter, nbytes); + + return buffer; + } + + data = gst_adapter_take (adapter, nbytes); + if (data == NULL) + return NULL; + + buffer = gst_buffer_new (); + GST_BUFFER_DATA (buffer) = data; + GST_BUFFER_MALLOCDATA (buffer) = data; + GST_BUFFER_SIZE (buffer) = nbytes; + + return buffer; +} + static gboolean plugin_init (GstPlugin * plugin)