From cc350794fbe9e138188457e0214c861ffe607d33 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Jul 2006 10:22:54 +0000 Subject: [PATCH] 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. --- ChangeLog | 12 +++ ext/libpng/gstpngdec.c | 170 ++++++++++++++++++++++++----------------- ext/libpng/gstpngdec.h | 3 +- 3 files changed, 114 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e800c6bff..dd901f6b84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-07-17 Wim Taymans + + * 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 * gst/rtp/Makefile.am: diff --git a/ext/libpng/gstpngdec.c b/ext/libpng/gstpngdec.c index d943d03cf1..d43fb40193 100644 --- a/ext/libpng/gstpngdec.c +++ b/ext/libpng/gstpngdec.c @@ -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. diff --git a/ext/libpng/gstpngdec.h b/ext/libpng/gstpngdec.h index 5b11d5e5e9..f7c4675a38 100644 --- a/ext/libpng/gstpngdec.h +++ b/ext/libpng/gstpngdec.h @@ -67,7 +67,8 @@ struct _GstPngDec gboolean framed; GstClockTime in_timestamp; GstClockTime in_duration; - GstSegment *segment; + + GstSegment segment; }; struct _GstPngDecClass