summaryrefslogtreecommitdiffstats
path: root/ext/libpng
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2006-07-03 15:31:22 +0000
committerEdward Hervey <bilboed@bilboed.com>2006-07-03 15:31:22 +0000
commit00e08a3f6eb6f504d9a42b7ee689d7c646de464a (patch)
tree6b1d82d8d138a1becb0631b2ef35cd199a44c575 /ext/libpng
parent663856a5144843cd0dcd524b4529be00d005c8c0 (diff)
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.
Diffstat (limited to 'ext/libpng')
-rw-r--r--ext/libpng/gstpngdec.c65
-rw-r--r--ext/libpng/gstpngdec.h1
2 files changed, 61 insertions, 5 deletions
diff --git a/ext/libpng/gstpngdec.c b/ext/libpng/gstpngdec.c
index 67f08783..d943d03c 100644
--- a/ext/libpng/gstpngdec.c
+++ b/ext/libpng/gstpngdec.c
@@ -158,6 +158,8 @@ gst_pngdec_init (GstPngDec * pngdec)
pngdec->in_timestamp = GST_CLOCK_TIME_NONE;
pngdec->in_duration = GST_CLOCK_TIME_NONE;
+
+ pngdec->segment = gst_segment_new ();
}
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
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");
+ if (!pngdec->buffer_out)
+ return;
+
if (GST_CLOCK_TIME_IS_VALID (pngdec->in_timestamp))
GST_BUFFER_TIMESTAMP (pngdec->buffer_out) = pngdec->in_timestamp;
if (GST_CLOCK_TIME_IS_VALID (pngdec->in_duration))
GST_BUFFER_DURATION (pngdec->buffer_out) = pngdec->in_duration;
- /* 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)));
+ /* buffer clipping */
+ if (buffer_clip (pngdec, 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;
if (pngdec->framed) {
@@ -516,6 +550,7 @@ gst_pngdec_chain (GstPad * pad, GstBuffer * buffer)
/* Progressive loading of the PNG image */
png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (buffer));
+ ret = pngdec->ret;
/* And release the buffer */
gst_buffer_unref (buffer);
@@ -559,9 +594,15 @@ gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:{
+ gdouble rate;
+ gboolean update;
+ gint64 start, stop, position;
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));
if (fmt == GST_FORMAT_TIME) {
pngdec->need_newsegment = FALSE;
@@ -572,6 +613,14 @@ gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
}
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:
GST_LOG_OBJECT (pngdec, "EOS");
gst_pngdec_libpng_clear (pngdec);
@@ -679,6 +728,8 @@ gst_pngdec_change_state (GstElement * element, GstStateChange transition)
gst_pngdec_libpng_init (pngdec);
pngdec->need_newsegment = TRUE;
pngdec->framed = FALSE;
+ pngdec->segment = gst_segment_new ();
+ gst_segment_init (pngdec->segment, GST_FORMAT_UNDEFINED);
break;
default:
break;
@@ -691,6 +742,10 @@ gst_pngdec_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_pngdec_libpng_clear (pngdec);
+ if (pngdec->segment) {
+ gst_segment_free (pngdec->segment);
+ pngdec->segment = NULL;
+ }
break;
default:
break;
diff --git a/ext/libpng/gstpngdec.h b/ext/libpng/gstpngdec.h
index c16e7a98..5b11d5e5 100644
--- a/ext/libpng/gstpngdec.h
+++ b/ext/libpng/gstpngdec.h
@@ -67,6 +67,7 @@ struct _GstPngDec
gboolean framed;
GstClockTime in_timestamp;
GstClockTime in_duration;
+ GstSegment *segment;
};
struct _GstPngDecClass