mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
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:
parent
663856a514
commit
00e08a3f6e
3 changed files with 70 additions and 5 deletions
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
/* buffer clipping */
|
||||||
|
if (buffer_clip (pngdec, pngdec->buffer_out)) {
|
||||||
/* Push our buffer and then EOS if needed */
|
/* Push our buffer and then EOS if needed */
|
||||||
GST_LOG_OBJECT (pngdec, "pushing buffer with ts=%" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (pngdec, "pushing buffer with ts=%" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (pngdec->buffer_out)));
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue