ext/libpng/gstpngdec.*: Implement buffer clipping/dropping using GstSegment.

Original commit message from CVS:
* ext/libpng/gstpngdec.c: (gst_pngdec_init), (user_info_callback),
(buffer_clip), (user_end_callback), (gst_pngdec_chain),
(gst_pngdec_sink_event), (gst_pngdec_change_state):
* ext/libpng/gstpngdec.h:
Implement buffer clipping/dropping using GstSegment.
This provides accurate seeking.
This commit is contained in:
Edward Hervey 2006-07-03 15:31:22 +00:00
parent 663856a514
commit 00e08a3f6e
3 changed files with 70 additions and 5 deletions

View file

@ -1,3 +1,12 @@
2006-07-03 Edward Hervey <edward@fluendo.com>
* ext/libpng/gstpngdec.c: (gst_pngdec_init), (user_info_callback),
(buffer_clip), (user_end_callback), (gst_pngdec_chain),
(gst_pngdec_sink_event), (gst_pngdec_change_state):
* ext/libpng/gstpngdec.h:
Implement buffer clipping/dropping using GstSegment.
This provides accurate seeking.
2006-07-03 Edward Hervey <edward@fluendo.com> 2006-07-03 Edward Hervey <edward@fluendo.com>
* gst/avi/gstavidemux.c: (gst_avi_demux_reset), * gst/avi/gstavidemux.c: (gst_avi_demux_reset),

View file

@ -158,6 +158,8 @@ gst_pngdec_init (GstPngDec * pngdec)
pngdec->in_timestamp = GST_CLOCK_TIME_NONE; pngdec->in_timestamp = GST_CLOCK_TIME_NONE;
pngdec->in_duration = GST_CLOCK_TIME_NONE; pngdec->in_duration = GST_CLOCK_TIME_NONE;
pngdec->segment = gst_segment_new ();
} }
static void static void
@ -230,6 +232,29 @@ user_endrow_callback (png_structp png_ptr, png_bytep new_row,
} }
} }
static gboolean
buffer_clip (GstPngDec * dec, GstBuffer * buffer)
{
gboolean res = TRUE;
gint64 cstart, cstop;
if ((!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))) ||
(!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buffer))) ||
(dec->segment->format != GST_FORMAT_TIME))
goto beach;
if ((res = gst_segment_clip (dec->segment, GST_FORMAT_TIME,
GST_BUFFER_TIMESTAMP (buffer),
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer),
&cstart, &cstop))) {
GST_BUFFER_TIMESTAMP (buffer) = cstart;
GST_BUFFER_DURATION (buffer) = cstop - cstart;
}
beach:
return res;
}
static void static void
user_end_callback (png_structp png_ptr, png_infop info) user_end_callback (png_structp png_ptr, png_infop info)
{ {
@ -239,16 +264,25 @@ user_end_callback (png_structp png_ptr, png_infop info)
GST_LOG_OBJECT (pngdec, "and we are done reading this image"); GST_LOG_OBJECT (pngdec, "and we are done reading this image");
if (!pngdec->buffer_out)
return;
if (GST_CLOCK_TIME_IS_VALID (pngdec->in_timestamp)) if (GST_CLOCK_TIME_IS_VALID (pngdec->in_timestamp))
GST_BUFFER_TIMESTAMP (pngdec->buffer_out) = pngdec->in_timestamp; GST_BUFFER_TIMESTAMP (pngdec->buffer_out) = pngdec->in_timestamp;
if (GST_CLOCK_TIME_IS_VALID (pngdec->in_duration)) if (GST_CLOCK_TIME_IS_VALID (pngdec->in_duration))
GST_BUFFER_DURATION (pngdec->buffer_out) = pngdec->in_duration; GST_BUFFER_DURATION (pngdec->buffer_out) = pngdec->in_duration;
/* Push our buffer and then EOS if needed */ /* buffer clipping */
GST_LOG_OBJECT (pngdec, "pushing buffer with ts=%" GST_TIME_FORMAT, if (buffer_clip (pngdec, pngdec->buffer_out)) {
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (pngdec->buffer_out))); /* Push our buffer and then EOS if needed */
GST_LOG_OBJECT (pngdec, "pushing buffer with ts=%" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (pngdec->buffer_out)));
pngdec->ret = gst_pad_push (pngdec->srcpad, pngdec->buffer_out); pngdec->ret = gst_pad_push (pngdec->srcpad, pngdec->buffer_out);
} else {
GST_LOG_OBJECT (pngdec, "dropped decoded buffer");
gst_buffer_unref (pngdec->buffer_out);
}
pngdec->buffer_out = NULL; pngdec->buffer_out = NULL;
if (pngdec->framed) { if (pngdec->framed) {
@ -516,6 +550,7 @@ gst_pngdec_chain (GstPad * pad, GstBuffer * buffer)
/* Progressive loading of the PNG image */ /* Progressive loading of the PNG image */
png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer), png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (buffer)); GST_BUFFER_SIZE (buffer));
ret = pngdec->ret;
/* And release the buffer */ /* And release the buffer */
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
@ -559,9 +594,15 @@ gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:{ case GST_EVENT_NEWSEGMENT:{
gdouble rate;
gboolean update;
gint64 start, stop, position;
GstFormat fmt; GstFormat fmt;
gst_event_parse_new_segment (event, NULL, NULL, &fmt, NULL, NULL, NULL); gst_event_parse_new_segment (event, &update, &rate, &fmt, &start, &stop,
&position);
gst_segment_set_newsegment (pngdec->segment, update, rate, fmt, start,
stop, position);
GST_LOG_OBJECT (pngdec, "NEWSEGMENT (%s)", gst_format_get_name (fmt)); GST_LOG_OBJECT (pngdec, "NEWSEGMENT (%s)", gst_format_get_name (fmt));
if (fmt == GST_FORMAT_TIME) { if (fmt == GST_FORMAT_TIME) {
pngdec->need_newsegment = FALSE; pngdec->need_newsegment = FALSE;
@ -572,6 +613,14 @@ gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
} }
break; break;
} }
case GST_EVENT_FLUSH_START:
gst_pngdec_libpng_clear (pngdec);
res = gst_pad_event_default (pad, event);
break;
case GST_EVENT_FLUSH_STOP:
gst_pngdec_libpng_init (pngdec);
res = gst_pad_event_default (pad, event);
break;
case GST_EVENT_EOS: case GST_EVENT_EOS:
GST_LOG_OBJECT (pngdec, "EOS"); GST_LOG_OBJECT (pngdec, "EOS");
gst_pngdec_libpng_clear (pngdec); gst_pngdec_libpng_clear (pngdec);
@ -679,6 +728,8 @@ gst_pngdec_change_state (GstElement * element, GstStateChange transition)
gst_pngdec_libpng_init (pngdec); gst_pngdec_libpng_init (pngdec);
pngdec->need_newsegment = TRUE; pngdec->need_newsegment = TRUE;
pngdec->framed = FALSE; pngdec->framed = FALSE;
pngdec->segment = gst_segment_new ();
gst_segment_init (pngdec->segment, GST_FORMAT_UNDEFINED);
break; break;
default: default:
break; break;
@ -691,6 +742,10 @@ gst_pngdec_change_state (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_pngdec_libpng_clear (pngdec); gst_pngdec_libpng_clear (pngdec);
if (pngdec->segment) {
gst_segment_free (pngdec->segment);
pngdec->segment = NULL;
}
break; break;
default: default:
break; break;

View file

@ -67,6 +67,7 @@ struct _GstPngDec
gboolean framed; gboolean framed;
GstClockTime in_timestamp; GstClockTime in_timestamp;
GstClockTime in_duration; GstClockTime in_duration;
GstSegment *segment;
}; };
struct _GstPngDecClass struct _GstPngDecClass