gstrtpbasepayloader: Add property for scaling RTP timestamp
authorTobias Ronge <tobiasr@axis.com>
Mon, 9 Mar 2020 14:26:42 +0000 (15:26 +0100)
committerTobias Ronge <tobiasr@axis.com>
Mon, 16 Mar 2020 10:25:44 +0000 (10:25 +0000)
This patch introduces a property which, if set to FALSE, prevents RTP
basepayloader from scaling the RTP time when a segment's rate is not
equal to 1.0. The specification is ambiguous on this subject and some
clients expect the timestamps not to be scaled.

gst-libs/gst/rtp/gstrtpbasepayload.c

index 8167abc..1fe7cb1 100644 (file)
@@ -53,6 +53,7 @@ struct _GstRTPBasePayloadPrivate
   gint64 base_rtime;
   guint64 base_rtime_hz;
   guint64 running_time;
+  gboolean scale_rtptime;
 
   gint64 prop_max_ptime;
   gint64 caps_max_ptime;
@@ -94,6 +95,7 @@ enum
 #define DEFAULT_SOURCE_INFO             FALSE
 #define DEFAULT_ONVIF_NO_RATE_CONTROL   FALSE
 #define DEFAULT_TWCC_EXT_ID             0
+#define DEFAULT_SCALE_RTPTIME           TRUE
 
 enum
 {
@@ -113,6 +115,7 @@ enum
   PROP_SOURCE_INFO,
   PROP_ONVIF_NO_RATE_CONTROL,
   PROP_TWCC_EXT_ID,
+  PROP_SCALE_RTPTIME,
   PROP_LAST
 };
 
@@ -361,6 +364,24 @@ gst_rtp_base_payload_class_init (GstRTPBasePayloadClass * klass)
           0, 15, DEFAULT_TWCC_EXT_ID,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstRTPBasePayload:scale-rtptime:
+   *
+   * Make the RTP packets' timestamps be scaled with the segment's rate
+   * (corresponding to RTSP speed parameter). Disabling this property means
+   * the timestamps will not be affected by the set delivery speed (RTSP speed).
+   * 
+   * Example: A server wants to allow streaming a recorded video in double 
+   * speed but still have the timestamps correspond to the position in the 
+   * video. This is achieved by the client setting RTSP Speed to 2 while the 
+   * server has this property disabled.
+   * 
+   * Since: 1.18
+   */
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SCALE_RTPTIME,
+      g_param_spec_boolean ("scale-rtptime", "Scale RTP time",
+          "Whether the RTP timestamp should be scaled with the rate (speed)",
+          DEFAULT_SCALE_RTPTIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   gstelement_class->change_state = gst_rtp_base_payload_change_state;
 
@@ -423,6 +444,7 @@ gst_rtp_base_payload_init (GstRTPBasePayload * rtpbasepayload, gpointer g_class)
   rtpbasepayload->priv->base_offset = GST_BUFFER_OFFSET_NONE;
   rtpbasepayload->priv->base_rtime_hz = GST_BUFFER_OFFSET_NONE;
   rtpbasepayload->priv->onvif_no_rate_control = DEFAULT_ONVIF_NO_RATE_CONTROL;
+  rtpbasepayload->priv->scale_rtptime = DEFAULT_SCALE_RTPTIME;
 
   rtpbasepayload->media = NULL;
   rtpbasepayload->encoding_name = NULL;
@@ -1332,7 +1354,7 @@ gst_rtp_base_payload_prepare_push (GstRTPBasePayload * payload,
     guint64 rtime_hz;
 
     /* no offset, use the gstreamer pts */
-    if (priv->onvif_no_rate_control)
+    if (priv->onvif_no_rate_control || !priv->scale_rtptime)
       rtime_ns = gst_segment_to_stream_time (&payload->segment,
           GST_FORMAT_TIME, data.pts);
     else
@@ -1617,6 +1639,9 @@ gst_rtp_base_payload_set_property (GObject * object, guint prop_id,
     case PROP_TWCC_EXT_ID:
       priv->twcc_ext_id = g_value_get_uint (value);
       break;
+    case PROP_SCALE_RTPTIME:
+      priv->scale_rtptime = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1690,6 +1715,9 @@ gst_rtp_base_payload_get_property (GObject * object, guint prop_id,
     case PROP_TWCC_EXT_ID:
       g_value_set_uint (value, priv->twcc_ext_id);
       break;
+    case PROP_SCALE_RTPTIME:
+      g_value_set_boolean (value, priv->scale_rtptime);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;