rtph265depay: try to negotiate an allocator with downstream
authorTim-Philipp Müller <tim@centricular.com>
Fri, 16 Jun 2017 11:30:13 +0000 (12:30 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 23 Nov 2017 08:36:15 +0000 (09:36 +0100)
gst/rtp/gstrtph265depay.c
gst/rtp/gstrtph265depay.h

index e7d5d40..e2caa9a 100644 (file)
@@ -157,7 +157,7 @@ gst_rtp_h265_depay_init (GstRtpH265Depay * rtph265depay)
 }
 
 static void
-gst_rtp_h265_depay_reset (GstRtpH265Depay * rtph265depay)
+gst_rtp_h265_depay_reset (GstRtpH265Depay * rtph265depay, gboolean hard)
 {
   gst_adapter_clear (rtph265depay->adapter);
   rtph265depay->wait_start = TRUE;
@@ -170,6 +170,14 @@ gst_rtp_h265_depay_reset (GstRtpH265Depay * rtph265depay)
   g_ptr_array_set_size (rtph265depay->vps, 0);
   g_ptr_array_set_size (rtph265depay->sps, 0);
   g_ptr_array_set_size (rtph265depay->pps, 0);
+
+  if (hard) {
+    if (rtph265depay->allocator != NULL) {
+      gst_object_unref (rtph265depay->allocator);
+      rtph265depay->allocator = NULL;
+    }
+    gst_allocation_params_init (&rtph265depay->params);
+  }
 }
 
 static void
@@ -292,6 +300,44 @@ parse_pps (GstMapInfo * map, guint32 * sps_id, guint32 * pps_id)
   return TRUE;
 }
 
+static gboolean
+gst_rtp_h265_depay_set_output_caps (GstRtpH265Depay * rtph265depay,
+    GstCaps * caps)
+{
+  GstAllocationParams params;
+  GstAllocator *allocator = NULL;
+  GstPad *srcpad;
+  gboolean res;
+
+  gst_allocation_params_init (&params);
+
+  srcpad = GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph265depay);
+
+  res = gst_pad_set_caps (srcpad, caps);
+
+  if (res) {
+    GstQuery *query;
+
+    query = gst_query_new_allocation (caps, TRUE);
+    if (!gst_pad_peer_query (srcpad, query)) {
+      GST_DEBUG_OBJECT (rtph265depay, "downstream ALLOCATION query failed");
+    }
+
+    if (gst_query_get_n_allocation_params (query) > 0) {
+      gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
+    }
+
+    gst_query_unref (query);
+  }
+
+  if (rtph265depay->allocator)
+    gst_object_unref (rtph265depay->allocator);
+
+  rtph265depay->allocator = allocator;
+  rtph265depay->params = params;
+
+  return res;
+}
 
 static gboolean
 gst_rtp_h265_set_src_caps (GstRtpH265Depay * rtph265depay)
@@ -538,7 +584,7 @@ gst_rtp_h265_set_src_caps (GstRtpH265Depay * rtph265depay)
   }
 
   if (update_caps) {
-    res = gst_pad_set_caps (srcpad, srccaps);
+    res = gst_rtp_h265_depay_set_output_caps (rtph265depay, srccaps);
   } else {
     res = TRUE;
   }
@@ -1444,7 +1490,7 @@ gst_rtp_h265_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * event)
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_STOP:
-      gst_rtp_h265_depay_reset (rtph265depay);
+      gst_rtp_h265_depay_reset (rtph265depay, FALSE);
       break;
     default:
       break;
@@ -1467,7 +1513,7 @@ gst_rtp_h265_depay_change_state (GstElement * element,
     case GST_STATE_CHANGE_NULL_TO_READY:
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_rtp_h265_depay_reset (rtph265depay);
+      gst_rtp_h265_depay_reset (rtph265depay, TRUE);
       break;
     default:
       break;
@@ -1476,6 +1522,9 @@ gst_rtp_h265_depay_change_state (GstElement * element,
   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      gst_rtp_h265_depay_reset (rtph265depay, TRUE);
+      break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       break;
     default:
index ecb910d..c5a9f69 100644 (file)
@@ -80,6 +80,10 @@ struct _GstRtpH265Depay
   GPtrArray *sps;
   GPtrArray *pps;
   gboolean new_codec_data;
+
+  /* downstream allocator */
+  GstAllocator *allocator;
+  GstAllocationParams params;
 };
 
 struct _GstRtpH265DepayClass