various: fix pad template leaks
[platform/upstream/gstreamer.git] / gst / rtp / gstrtpjpegdepay.c
index 87c7158..3c84397 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (rtpjpegdepay_debug);
 #define GST_CAT_DEFAULT (rtpjpegdepay_debug)
 
-/* elementfactory information */
-static const GstElementDetails gst_rtp_jpegdepay_details =
-GST_ELEMENT_DETAILS ("RTP JPEG depayloader",
-    "Codec/Depayloader/Network",
-    "Extracts JPEG video from RTP packets (RFC 2435)",
-    "Wim Taymans <wim.taymans@gmail.com>");
-
 static GstStaticPadTemplate gst_rtp_jpeg_depay_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -78,6 +71,9 @@ GST_BOILERPLATE (GstRtpJPEGDepay, gst_rtp_jpeg_depay, GstBaseRTPDepayload,
 
 static void gst_rtp_jpeg_depay_finalize (GObject * object);
 
+static GstStateChangeReturn gst_rtp_jpeg_depay_change_state (GstElement *
+    element, GstStateChange transition);
+
 static gboolean gst_rtp_jpeg_depay_setcaps (GstBaseRTPDepayload * depayload,
     GstCaps * caps);
 static GstBuffer *gst_rtp_jpeg_depay_process (GstBaseRTPDepayload * depayload,
@@ -88,25 +84,32 @@ gst_rtp_jpeg_depay_base_init (gpointer klass)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_rtp_jpeg_depay_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_rtp_jpeg_depay_sink_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_rtp_jpeg_depay_src_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_rtp_jpeg_depay_sink_template);
 
-  gst_element_class_set_details (element_class, &gst_rtp_jpegdepay_details);
+  gst_element_class_set_details_simple (element_class, "RTP JPEG depayloader",
+      "Codec/Depayloader/Network/RTP",
+      "Extracts JPEG video from RTP packets (RFC 2435)",
+      "Wim Taymans <wim.taymans@gmail.com>");
 }
 
 static void
 gst_rtp_jpeg_depay_class_init (GstRtpJPEGDepayClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
 
   gobject_class->finalize = gst_rtp_jpeg_depay_finalize;
 
+  gstelement_class->change_state = gst_rtp_jpeg_depay_change_state;
+
   gstbasertpdepayload_class->set_caps = gst_rtp_jpeg_depay_setcaps;
   gstbasertpdepayload_class->process = gst_rtp_jpeg_depay_process;
 
@@ -122,12 +125,35 @@ gst_rtp_jpeg_depay_init (GstRtpJPEGDepay * rtpjpegdepay,
 }
 
 static void
+gst_rtp_jpeg_depay_reset (GstRtpJPEGDepay * depay)
+{
+  gint i;
+
+  depay->width = 0;
+  depay->height = 0;
+  depay->media_width = 0;
+  depay->media_height = 0;
+  depay->frate_num = 0;
+  depay->frate_denom = 1;
+  depay->discont = TRUE;
+
+  for (i = 0; i < 255; i++) {
+    g_free (depay->qtables[i]);
+    depay->qtables[i] = NULL;
+  }
+
+  gst_adapter_clear (depay->adapter);
+}
+
+static void
 gst_rtp_jpeg_depay_finalize (GObject * object)
 {
   GstRtpJPEGDepay *rtpjpegdepay;
 
   rtpjpegdepay = GST_RTP_JPEG_DEPAY (object);
 
+  gst_rtp_jpeg_depay_reset (rtpjpegdepay);
+
   g_object_unref (rtpjpegdepay->adapter);
   rtpjpegdepay->adapter = NULL;
 
@@ -434,15 +460,23 @@ gst_rtp_jpeg_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
   if (media_attr) {
     GValue src = { 0 };
     GValue dest = { 0 };
+    gchar *s;
+
+    /* canonicalise floating point string so we can handle framerate strings
+     * in the form "24.930" or "24,930" irrespective of the current locale */
+    s = g_strdup (media_attr);
+    g_strdelimit (s, ",", '.');
 
     /* convert the float to a fraction */
     g_value_init (&src, G_TYPE_DOUBLE);
-    g_value_set_double (&src, atof (media_attr));
+    g_value_set_double (&src, g_ascii_strtod (s, NULL));
     g_value_init (&dest, GST_TYPE_FRACTION);
     g_value_transform (&src, &dest);
 
     rtpjpegdepay->frate_num = gst_value_get_fraction_numerator (&dest);
     rtpjpegdepay->frate_denom = gst_value_get_fraction_denominator (&dest);
+
+    g_free (s);
   }
 
   return TRUE;
@@ -465,6 +499,7 @@ gst_rtp_jpeg_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
 
   if (GST_BUFFER_IS_DISCONT (buf)) {
     gst_adapter_clear (rtpjpegdepay->adapter);
+    rtpjpegdepay->discont = TRUE;
   }
 
   payload_len = gst_rtp_buffer_get_payload_len (buf);
@@ -656,6 +691,11 @@ gst_rtp_jpeg_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
     }
     outbuf = gst_adapter_take_buffer (rtpjpegdepay->adapter, avail);
 
+    if (rtpjpegdepay->discont) {
+      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
+      rtpjpegdepay->discont = FALSE;
+    }
+
     GST_DEBUG_OBJECT (rtpjpegdepay, "returning %u bytes", avail);
   }
 
@@ -681,9 +721,39 @@ no_qtable:
   }
 }
 
+
+static GstStateChangeReturn
+gst_rtp_jpeg_depay_change_state (GstElement * element,
+    GstStateChange transition)
+{
+  GstRtpJPEGDepay *rtpjpegdepay;
+  GstStateChangeReturn ret;
+
+  rtpjpegdepay = GST_RTP_JPEG_DEPAY (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      gst_rtp_jpeg_depay_reset (rtpjpegdepay);
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+
 gboolean
 gst_rtp_jpeg_depay_plugin_init (GstPlugin * plugin)
 {
   return gst_element_register (plugin, "rtpjpegdepay",
-      GST_RANK_MARGINAL, GST_TYPE_RTP_JPEG_DEPAY);
+      GST_RANK_SECONDARY, GST_TYPE_RTP_JPEG_DEPAY);
 }