various: fix pad template leaks
[platform/upstream/gstreamer.git] / gst / rtpmanager / gstrtpptdemux.c
index 957ebdb..0679438 100644 (file)
@@ -132,6 +132,9 @@ static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux);
 
 static GstRtpPtDemuxPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);
 
+static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event);
+
+
 static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 };
 
 static void
@@ -139,10 +142,10 @@ gst_rtp_pt_demux_base_init (gpointer g_class)
 {
   GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class);
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&rtp_pt_demux_sink_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&rtp_pt_demux_src_template));
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &rtp_pt_demux_sink_template);
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &rtp_pt_demux_src_template);
 
   gst_element_class_set_details_simple (gstelement_klass, "RTP Demux",
       "Demux/Network/RTP",
@@ -329,6 +332,7 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
     srcpad = gst_pad_new_from_template (templ, padname);
     gst_pad_use_fixed_caps (srcpad);
     g_free (padname);
+    gst_pad_set_event_function (srcpad, gst_rtp_pt_demux_src_event);
 
     caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
     if (!caps)
@@ -429,7 +433,11 @@ gst_rtp_pt_demux_sink_event (GstPad * pad, GstEvent * event)
   GstRtpPtDemux *rtpdemux;
   gboolean res = FALSE;
 
-  rtpdemux = GST_RTP_PT_DEMUX (GST_PAD_PARENT (pad));
+  rtpdemux = GST_RTP_PT_DEMUX (gst_pad_get_parent (pad));
+  if (G_UNLIKELY (rtpdemux == NULL)) {
+    gst_event_unref (event);
+    return FALSE;
+  }
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_CUSTOM_DOWNSTREAM:
@@ -444,19 +452,65 @@ gst_rtp_pt_demux_sink_event (GstPad * pad, GstEvent * event)
 
         if (rtpdemuxpad)
           res = gst_pad_push_event (rtpdemuxpad->pad, event);
+        else
+          gst_event_unref (event);
 
       } else {
         res = gst_pad_event_default (pad, event);
       }
+      break;
     }
     default:
       res = gst_pad_event_default (pad, event);
       break;
   }
+
+  gst_object_unref (rtpdemux);
   return res;
 }
 
 
+static gboolean
+gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event)
+{
+  GstRtpPtDemux *demux;
+  const GstStructure *s;
+
+  demux = GST_RTP_PT_DEMUX (gst_pad_get_parent (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CUSTOM_UPSTREAM:
+    case GST_EVENT_CUSTOM_BOTH:
+    case GST_EVENT_CUSTOM_BOTH_OOB:
+      s = gst_event_get_structure (event);
+      if (s && !gst_structure_has_field (s, "payload")) {
+        GSList *walk;
+
+        for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
+          GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data;
+
+          if (dpad->pad == pad) {
+            event =
+                GST_EVENT_CAST (gst_mini_object_make_writable
+                (GST_MINI_OBJECT_CAST (event)));
+            gst_structure_set (event->structure,
+                "payload", G_TYPE_UINT, dpad->pt, NULL);
+            break;
+          }
+        }
+      }
+      break;
+    default:
+      break;
+  }
+
+  gst_object_unref (demux);
+
+  return gst_pad_event_default (pad, event);
+}
+
+
+
 /*
  * Reserves resources for the object.
  */