[gst-cvs] gst-plugins-good: [MOVED FROM BAD 06/56] gst/deinterlace2/gstdeinterlace2.* : Reset element state on PAUSED->READY properly, don' t leak any buffers when finali...

Sebastian Dröge slomo at kemper.freedesktop.org
Wed May 13 01:50:05 PDT 2009


Module: gst-plugins-good
Branch: master
Commit: e094cde977ea5853e5f6129c5924b6491e98212d
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=e094cde977ea5853e5f6129c5924b6491e98212d

Author: Sebastian Dröge <slomo at circular-chaos.org>
Date:   Fri Jun 20 14:35:25 2008 +0000

[MOVED FROM BAD 06/56] gst/deinterlace2/gstdeinterlace2.*: Reset element state on PAUSED->READY properly, don't leak any buffers when finali...

Original commit message from CVS:
* gst/deinterlace2/gstdeinterlace2.c:
(gst_deinterlace2_class_init), (gst_deinterlace2_init),
(gst_deinterlace2_reset_history), (gst_deinterlace2_reset),
(gst_deinterlace2_finalize), (gst_deinterlace2_chain),
(gst_deinterlace2_sink_event), (gst_deinterlace2_change_state),
(gst_deinterlace2_src_query):
* gst/deinterlace2/gstdeinterlace2.h:
Reset element state on PAUSED->READY properly, don't leak any buffers
when finalizing, allocate buffers with gst_pad_alloc_buffer() and
properly return flow returns from gst_pad_push() instead of ignoring them.

---

 gst/deinterlace2/gstdeinterlace2.c |   87 +++++++++++++++++++++++++++---------
 gst/deinterlace2/gstdeinterlace2.h |    2 -
 2 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/gst/deinterlace2/gstdeinterlace2.c b/gst/deinterlace2/gstdeinterlace2.c
index 450a31c..a19ecda 100644
--- a/gst/deinterlace2/gstdeinterlace2.c
+++ b/gst/deinterlace2/gstdeinterlace2.c
@@ -30,6 +30,8 @@
 #include "tvtime/plugins.h"
 #include "tvtime/speedy.h"
 
+#include <string.h>
+
 GST_DEBUG_CATEGORY_STATIC (deinterlace2_debug);
 #define GST_CAT_DEFAULT (deinterlace2_debug)
 
@@ -146,6 +148,8 @@ static const GstQueryType *gst_deinterlace2_src_query_types (GstPad * pad);
 
 static void gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object);
 
+static void gst_deinterlace2_reset (GstDeinterlace2 * object);
+
 GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement,
     GST_TYPE_ELEMENT);
 
@@ -183,7 +187,7 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
           "Method",
           "Deinterlace Method",
           GST_TYPE_DEINTERLACE2_METHOD,
-          GST_DEINTERLACE2_GREEDY_H, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
+          GST_DEINTERLACE2_TOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
   g_object_class_install_property (gobject_class, ARG_FIELDS,
@@ -243,22 +247,45 @@ gst_deinterlace2_init (GstDeinterlace2 * object, GstDeinterlace2Class * klass)
   object->pMemcpy = speedy_memcpy;
 
   object->method = dscaler_tomsmocomp_get_method ();
+  object->field_layout = GST_DEINTERLACE2_LAYOUT_AUTO;
+  object->fields = GST_DEINTERLACE2_ALL;
+
+  gst_deinterlace2_reset (object);
+}
 
+static void
+gst_deinterlace2_reset_history (GstDeinterlace2 * object)
+{
+  gint i;
+
+  for (i = 0; i < object->history_count; i++) {
+    if (object->field_history[i].buf) {
+      gst_buffer_unref (object->field_history[i].buf);
+      object->field_history[i].buf = NULL;
+    }
+  }
+  memset (object->field_history, 0, MAX_FIELD_HISTORY * sizeof (GstPicture));
   object->history_count = 0;
+}
 
-  object->field_layout = GST_DEINTERLACE2_LAYOUT_AUTO;
+static void
+gst_deinterlace2_reset (GstDeinterlace2 * object)
+{
+  if (object->out_buf) {
+    gst_buffer_unref (object->out_buf);
+    object->out_buf = NULL;
+  }
 
-  object->out_buf = NULL;
   object->output_stride = 0;
   object->line_length = 0;
   object->frame_width = 0;
   object->frame_height = 0;
+  object->frame_rate_n = 0;
+  object->frame_rate_d = 0;
   object->field_height = 0;
   object->field_stride = 0;
 
-  object->fields = GST_DEINTERLACE2_ALL;
-
-  object->bottom_field = TRUE;
+  gst_deinterlace2_reset_history (object);
 }
 
 static void
@@ -349,7 +376,9 @@ gst_deinterlace2_get_property (GObject * _object, guint prop_id,
 static void
 gst_deinterlace2_finalize (GObject * object)
 {
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  gst_deinterlace2_reset (GST_DEINTERLACE2 (object));
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static GstBuffer *
@@ -544,12 +573,11 @@ gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object)
 static GstFlowReturn
 gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
 {
-  //GstBuffer *out_buf = NULL;
   GstDeinterlace2 *object = NULL;
 
   GstClockTime timestamp;
 
-  //GstFlowReturn ret = GST_FLOW_OK;
+  GstFlowReturn ret = GST_FLOW_OK;
 
   object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
 
@@ -581,8 +609,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
       GST_DEBUG ("deinterlacing top field");
 
       /* create new buffer */
-      object->out_buf = gst_buffer_new_and_alloc (object->frame_size);
-      gst_buffer_set_caps (object->out_buf, GST_PAD_CAPS (object->srcpad));
+      ret = gst_pad_alloc_buffer_and_set_caps (object->srcpad,
+          GST_BUFFER_OFFSET_NONE, object->frame_size,
+          GST_PAD_CAPS (object->srcpad), &object->out_buf);
+      if (ret != GST_FLOW_OK)
+        return ret;
 
       /* do magic calculus */
       if (object->method->deinterlace_frame != NULL) {
@@ -593,7 +624,10 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
         gst_buffer_unref (buf);
 
         GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
-        gst_pad_push (object->srcpad, object->out_buf);
+        ret = gst_pad_push (object->srcpad, object->out_buf);
+        object->out_buf = NULL;
+        if (ret != GST_FLOW_OK)
+          return ret;
       }
     }
     /* no calculation done: remove excess field */
@@ -613,8 +647,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
       GST_DEBUG ("deinterlacing bottom field");
 
       /* create new buffer */
-      object->out_buf = gst_buffer_new_and_alloc (object->frame_size);
-      gst_buffer_set_caps (object->out_buf, GST_PAD_CAPS (object->srcpad));
+      ret = gst_pad_alloc_buffer_and_set_caps (object->srcpad,
+          GST_BUFFER_OFFSET_NONE, object->frame_size,
+          GST_PAD_CAPS (object->srcpad), &object->out_buf);
+      if (ret != GST_FLOW_OK)
+        return ret;
 
       /* do magic calculus */
       if (object->method->deinterlace_frame != NULL) {
@@ -625,7 +662,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
         gst_buffer_unref (buf);
 
         GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
-        gst_pad_push (object->srcpad, object->out_buf);
+        ret = gst_pad_push (object->srcpad, object->out_buf);
+        object->out_buf = NULL;
+
+        if (ret != GST_FLOW_OK)
+          return ret;
       }
     }
     /* no calculation done: remove excess field */
@@ -639,11 +680,14 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
 
   } else {
     object->out_buf = gst_deinterlace2_pop_history (object);
-    gst_pad_push (object->srcpad, object->out_buf);
+    ret = gst_pad_push (object->srcpad, object->out_buf);
+    object->out_buf = NULL;
+    if (ret != GST_FLOW_OK)
+      return ret;
   }
   GST_DEBUG ("----chain end ----\n\n");
 
-  return GST_FLOW_OK;
+  return ret;
 }
 
 static gboolean
@@ -729,7 +773,7 @@ gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
     case GST_EVENT_EOS:
     case GST_EVENT_NEWSEGMENT:
-      /* TODO: reset history */
+      gst_deinterlace2_reset_history (object);
 
       /* fall through */
     default:
@@ -746,6 +790,8 @@ gst_deinterlace2_change_state (GstElement * element, GstStateChange transition)
 {
   GstStateChangeReturn ret;
 
+  GstDeinterlace2 *object = GST_DEINTERLACE2 (element);
+
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
       break;
@@ -765,7 +811,7 @@ gst_deinterlace2_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
-      /* TODO: reset history, clean up, etc */
+      gst_deinterlace2_reset (object);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
     default:
@@ -823,10 +869,7 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
               GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
               GST_TIME_ARGS (min), GST_TIME_ARGS (max));
 
-          /* TODO: calculate our own latency from framerate
-           *       and object->method->fields_required */
           /* add our own latency */
-
           latency =
               gst_util_uint64_scale (object->method->fields_required *
               GST_SECOND, object->frame_rate_d, object->frame_rate_n);
diff --git a/gst/deinterlace2/gstdeinterlace2.h b/gst/deinterlace2/gstdeinterlace2.h
index b15fa2f..1777f7c 100644
--- a/gst/deinterlace2/gstdeinterlace2.h
+++ b/gst/deinterlace2/gstdeinterlace2.h
@@ -252,8 +252,6 @@ struct _GstDeinterlace2
      need not match the pixel width
    */
   guint field_stride;
-
-  gboolean bottom_field;
 };
 
 struct _GstDeinterlace2Class





More information about the Gstreamer-commits mailing list