mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
ext/libpng/gstpngdec.*: Use statically allocated segment instead of leaking.
Original commit message from CVS: * ext/libpng/gstpngdec.c: (gst_pngdec_init), (buffer_clip), (gst_pngdec_caps_create_and_set), (gst_pngdec_task), (gst_pngdec_chain), (gst_pngdec_sink_event), (gst_pngdec_libpng_init), (gst_pngdec_change_state), (gst_pngdec_sink_activate_push): * ext/libpng/gstpngdec.h: Use statically allocated segment instead of leaking. Various cleanups. Fix flush and seek handling.
This commit is contained in:
parent
f6a274239a
commit
cc350794fb
3 changed files with 114 additions and 71 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2006-07-17 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* ext/libpng/gstpngdec.c: (gst_pngdec_init), (buffer_clip),
|
||||
(gst_pngdec_caps_create_and_set), (gst_pngdec_task),
|
||||
(gst_pngdec_chain), (gst_pngdec_sink_event),
|
||||
(gst_pngdec_libpng_init), (gst_pngdec_change_state),
|
||||
(gst_pngdec_sink_activate_push):
|
||||
* ext/libpng/gstpngdec.h:
|
||||
Use statically allocated segment instead of leaking.
|
||||
Various cleanups.
|
||||
Fix flush and seek handling.
|
||||
|
||||
2006-07-16 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtp/Makefile.am:
|
||||
|
|
|
@ -159,7 +159,7 @@ gst_pngdec_init (GstPngDec * pngdec)
|
|||
pngdec->in_timestamp = GST_CLOCK_TIME_NONE;
|
||||
pngdec->in_duration = GST_CLOCK_TIME_NONE;
|
||||
|
||||
pngdec->segment = gst_segment_new ();
|
||||
gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -240,10 +240,10 @@ buffer_clip (GstPngDec * dec, GstBuffer * buffer)
|
|||
|
||||
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))
|
||||
(dec->segment.format != GST_FORMAT_TIME))
|
||||
goto beach;
|
||||
|
||||
if ((res = gst_segment_clip (dec->segment, GST_FORMAT_TIME,
|
||||
if ((res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
|
||||
GST_BUFFER_TIMESTAMP (buffer),
|
||||
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer),
|
||||
&cstart, &cstop))) {
|
||||
|
@ -403,7 +403,7 @@ gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
|
|||
default:
|
||||
GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||
("pngdec does not support this color type"));
|
||||
ret = GST_FLOW_ERROR;
|
||||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -420,9 +420,8 @@ gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
|
|||
gst_caps_unref (caps);
|
||||
gst_object_unref (templ);
|
||||
|
||||
if (!gst_pad_set_caps (pngdec->srcpad, res)) {
|
||||
ret = GST_FLOW_ERROR;
|
||||
}
|
||||
if (!gst_pad_set_caps (pngdec->srcpad, res))
|
||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
|
||||
GST_DEBUG_OBJECT (pngdec, "our caps %" GST_PTR_FORMAT, res);
|
||||
|
||||
|
@ -505,13 +504,15 @@ gst_pngdec_task (GstPad * pad)
|
|||
return;
|
||||
|
||||
pause:
|
||||
GST_LOG_OBJECT (pngdec, "pausing task, reason %s", gst_flow_get_name (ret));
|
||||
gst_pad_pause_task (pngdec->sinkpad);
|
||||
if (GST_FLOW_IS_FATAL (ret)) {
|
||||
gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
|
||||
GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
|
||||
(_("Internal data stream error.")),
|
||||
("stream stopped, reason %s", gst_flow_get_name (ret)));
|
||||
{
|
||||
GST_LOG_OBJECT (pngdec, "pausing task, reason %s", gst_flow_get_name (ret));
|
||||
gst_pad_pause_task (pngdec->sinkpad);
|
||||
if (GST_FLOW_IS_FATAL (ret)) {
|
||||
gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
|
||||
GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
|
||||
(_("Internal data stream error.")),
|
||||
("stream stopped, reason %s", gst_flow_get_name (ret)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,25 +522,23 @@ gst_pngdec_chain (GstPad * pad, GstBuffer * buffer)
|
|||
GstPngDec *pngdec;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
pngdec = GST_PNGDEC (GST_OBJECT_PARENT (pad));
|
||||
pngdec = GST_PNGDEC (gst_pad_get_parent (pad));
|
||||
|
||||
GST_LOG_OBJECT (pngdec, "Got buffer, size=%u", GST_BUFFER_SIZE (buffer));
|
||||
|
||||
if (!pngdec->setup) {
|
||||
GST_LOG ("we are not configured yet");
|
||||
ret = GST_FLOW_WRONG_STATE;
|
||||
goto beach;
|
||||
}
|
||||
if (G_UNLIKELY (!pngdec->setup))
|
||||
goto not_configured;
|
||||
|
||||
/* Something is going wrong in our callbacks */
|
||||
if (pngdec->ret != GST_FLOW_OK) {
|
||||
ret = pngdec->ret;
|
||||
ret = pngdec->ret;
|
||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||
GST_WARNING_OBJECT (pngdec, "we have a pending return code of %d", ret);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
/* Let libpng come back here on error */
|
||||
if (setjmp (png_jmpbuf (pngdec->png))) {
|
||||
GST_WARNING ("error during decoding");
|
||||
GST_WARNING_OBJECT (pngdec, "error during decoding");
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto beach;
|
||||
}
|
||||
|
@ -550,13 +549,25 @@ 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));
|
||||
|
||||
/* grab new return code */
|
||||
ret = pngdec->ret;
|
||||
|
||||
/* And release the buffer */
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
beach:
|
||||
gst_object_unref (pngdec);
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
not_configured:
|
||||
{
|
||||
GST_LOG_OBJECT (pngdec, "we are not configured yet");
|
||||
ret = GST_FLOW_WRONG_STATE;
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -594,40 +605,49 @@ gst_pngdec_sink_event (GstPad * pad, GstEvent * event)
|
|||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_NEWSEGMENT:{
|
||||
gdouble rate;
|
||||
gdouble rate, arate;
|
||||
gboolean update;
|
||||
gint64 start, stop, position;
|
||||
GstFormat fmt;
|
||||
|
||||
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_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
|
||||
&start, &stop, &position);
|
||||
|
||||
gst_segment_set_newsegment_full (&pngdec->segment, update, rate, arate,
|
||||
fmt, start, stop, position);
|
||||
|
||||
GST_LOG_OBJECT (pngdec, "NEWSEGMENT (%s)", gst_format_get_name (fmt));
|
||||
|
||||
if (fmt == GST_FORMAT_TIME) {
|
||||
pngdec->need_newsegment = FALSE;
|
||||
res = gst_pad_event_default (pad, event);
|
||||
res = gst_pad_push_event (pngdec->srcpad, event);
|
||||
} else {
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
}
|
||||
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_clear (pngdec);
|
||||
gst_pngdec_libpng_init (pngdec);
|
||||
res = gst_pad_event_default (pad, event);
|
||||
png_set_progressive_read_fn (pngdec->png, pngdec,
|
||||
user_info_callback, user_endrow_callback, user_end_callback);
|
||||
pngdec->ret = GST_FLOW_OK;
|
||||
gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
|
||||
res = gst_pad_push_event (pngdec->srcpad, event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_EOS:
|
||||
{
|
||||
GST_LOG_OBJECT (pngdec, "EOS");
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
res = gst_pad_event_default (pad, event);
|
||||
pngdec->ret = GST_FLOW_UNEXPECTED;
|
||||
res = gst_pad_push_event (pngdec->srcpad, event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_event_default (pad, event);
|
||||
res = gst_pad_push_event (pngdec->srcpad, event);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -679,40 +699,51 @@ gst_pngdec_libpng_init (GstPngDec * pngdec)
|
|||
{
|
||||
g_return_val_if_fail (GST_IS_PNGDEC (pngdec), FALSE);
|
||||
|
||||
if (pngdec->setup) {
|
||||
goto beach;
|
||||
}
|
||||
if (pngdec->setup)
|
||||
return TRUE;
|
||||
|
||||
GST_LOG ("init libpng structures");
|
||||
|
||||
/* initialize png struct stuff */
|
||||
pngdec->png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
|
||||
(png_voidp) NULL, user_error_fn, user_warning_fn);
|
||||
|
||||
if (pngdec->png == NULL) {
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize png structure"));
|
||||
goto beach;
|
||||
}
|
||||
if (pngdec->png == NULL)
|
||||
goto init_failed;
|
||||
|
||||
pngdec->info = png_create_info_struct (pngdec->png);
|
||||
if (pngdec->info == NULL) {
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize info structure"));
|
||||
goto beach;
|
||||
}
|
||||
if (pngdec->info == NULL)
|
||||
goto info_failed;
|
||||
|
||||
pngdec->endinfo = png_create_info_struct (pngdec->png);
|
||||
if (pngdec->endinfo == NULL) {
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize endinfo structure"));
|
||||
goto beach;
|
||||
}
|
||||
if (pngdec->endinfo == NULL)
|
||||
goto endinfo_failed;
|
||||
|
||||
pngdec->setup = TRUE;
|
||||
|
||||
beach:
|
||||
return pngdec->setup;
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
init_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize png structure"));
|
||||
return FALSE;
|
||||
}
|
||||
info_failed:
|
||||
{
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize info structure"));
|
||||
return FALSE;
|
||||
}
|
||||
endinfo_failed:
|
||||
{
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
GST_ELEMENT_ERROR (pngdec, LIBRARY, INIT, (NULL),
|
||||
("Failed to initialize endinfo structure"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
|
@ -728,8 +759,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);
|
||||
pngdec->ret = GST_FLOW_OK;
|
||||
gst_segment_init (&pngdec->segment, GST_FORMAT_UNDEFINED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -742,10 +773,6 @@ 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;
|
||||
|
@ -766,18 +793,21 @@ gst_pngdec_sink_activate_push (GstPad * sinkpad, gboolean active)
|
|||
|
||||
if (active) {
|
||||
/* Let libpng come back here on error */
|
||||
if (setjmp (png_jmpbuf (pngdec->png))) {
|
||||
GST_LOG ("failed setting up libpng jumb");
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
return FALSE;
|
||||
}
|
||||
if (setjmp (png_jmpbuf (pngdec->png)))
|
||||
goto setup_failed;
|
||||
|
||||
GST_LOG ("setting up progressive loading callbacks");
|
||||
png_set_progressive_read_fn (pngdec->png, pngdec,
|
||||
user_info_callback, user_endrow_callback, user_end_callback);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
setup_failed:
|
||||
{
|
||||
GST_LOG ("failed setting up libpng jmpbuf");
|
||||
gst_pngdec_libpng_clear (pngdec);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function gets called when we activate ourselves in pull mode.
|
||||
|
|
|
@ -67,7 +67,8 @@ struct _GstPngDec
|
|||
gboolean framed;
|
||||
GstClockTime in_timestamp;
|
||||
GstClockTime in_duration;
|
||||
GstSegment *segment;
|
||||
|
||||
GstSegment segment;
|
||||
};
|
||||
|
||||
struct _GstPngDecClass
|
||||
|
|
Loading…
Reference in a new issue