summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.com>2021-03-31 11:18:30 +0200
committerGuillaume Desmottes <guillaume.desmottes@collabora.com>2021-04-26 15:25:56 +0200
commit41ba8c1b00f5ad5f27c37b97ddee196d9d6e6d6a (patch)
treebb1e1d639d1422ca682201ffa517b183ee79952e /gst
parenta0067316e741e20e1ecbb01b3a3005fb64952eb7 (diff)
rtpopuspay: add DTX support
If enabled, the payloader won't transmit empty frames. Can be tested using: opusenc dtx=true bitrate-type=vbr ! rtpopuspay dtx=true Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/967>
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/gstrtpopuspay.c70
-rw-r--r--gst/rtp/gstrtpopuspay.h2
2 files changed, 72 insertions, 0 deletions
diff --git a/gst/rtp/gstrtpopuspay.c b/gst/rtp/gstrtpopuspay.c
index bee7bb5b4..bb3bf6d5d 100644
--- a/gst/rtp/gstrtpopuspay.c
+++ b/gst/rtp/gstrtpopuspay.c
@@ -58,6 +58,13 @@
GST_DEBUG_CATEGORY_STATIC (rtpopuspay_debug);
#define GST_CAT_DEFAULT (rtpopuspay_debug)
+enum
+{
+ PROP_0,
+ PROP_DTX,
+};
+
+#define DEFAULT_DTX FALSE
static GstStaticPadTemplate gst_rtp_opus_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
@@ -90,24 +97,77 @@ G_DEFINE_TYPE (GstRtpOPUSPay, gst_rtp_opus_pay, GST_TYPE_RTP_BASE_PAYLOAD);
GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (rtpopuspay, "rtpopuspay",
GST_RANK_PRIMARY, GST_TYPE_RTP_OPUS_PAY, rtp_element_init (plugin));
+#define GST_RTP_OPUS_PAY_CAST(obj) ((GstRtpOPUSPay *)(obj))
+
+static void
+gst_rtp_opus_pay_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+ GstRtpOPUSPay *self = GST_RTP_OPUS_PAY (object);
+
+ switch (prop_id) {
+ case PROP_DTX:
+ self->dtx = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_rtp_opus_pay_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ GstRtpOPUSPay *self = GST_RTP_OPUS_PAY (object);
+
+ switch (prop_id) {
+ case PROP_DTX:
+ g_value_set_boolean (value, self->dtx);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
static void
gst_rtp_opus_pay_class_init (GstRtpOPUSPayClass * klass)
{
GstRTPBasePayloadClass *gstbasertppayload_class;
GstElementClass *element_class;
+ GObjectClass *gobject_class;
gstbasertppayload_class = (GstRTPBasePayloadClass *) klass;
element_class = GST_ELEMENT_CLASS (klass);
+ gobject_class = (GObjectClass *) klass;
gstbasertppayload_class->set_caps = gst_rtp_opus_pay_setcaps;
gstbasertppayload_class->get_caps = gst_rtp_opus_pay_getcaps;
gstbasertppayload_class->handle_buffer = gst_rtp_opus_pay_handle_buffer;
+ gobject_class->set_property = gst_rtp_opus_pay_set_property;
+ gobject_class->get_property = gst_rtp_opus_pay_get_property;
+
gst_element_class_add_static_pad_template (element_class,
&gst_rtp_opus_pay_src_template);
gst_element_class_add_static_pad_template (element_class,
&gst_rtp_opus_pay_sink_template);
+ /**
+ * GstRtpOPUSPay:dtx:
+ *
+ * If enabled, the payloader will not transmit empty packets.
+ *
+ * Since: 1.20
+ */
+ g_object_class_install_property (gobject_class, PROP_DTX,
+ g_param_spec_boolean ("dtx", "Discontinuous Transmission",
+ "If enabled, the payloader will not transmit empty packets",
+ DEFAULT_DTX,
+ G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
+ G_PARAM_STATIC_STRINGS));
+
gst_element_class_set_static_metadata (element_class,
"RTP Opus payloader",
"Codec/Payloader/Network/RTP",
@@ -121,6 +181,7 @@ gst_rtp_opus_pay_class_init (GstRtpOPUSPayClass * klass)
static void
gst_rtp_opus_pay_init (GstRtpOPUSPay * rtpopuspay)
{
+ rtpopuspay->dtx = DEFAULT_DTX;
}
static gboolean
@@ -236,9 +297,18 @@ static GstFlowReturn
gst_rtp_opus_pay_handle_buffer (GstRTPBasePayload * basepayload,
GstBuffer * buffer)
{
+ GstRtpOPUSPay *self = GST_RTP_OPUS_PAY_CAST (basepayload);
GstBuffer *outbuf;
GstClockTime pts, dts, duration;
+ /* DTX packets are zero-length frames, with a 1 or 2-bytes header */
+ if (self->dtx && gst_buffer_get_size (buffer) <= 2) {
+ GST_LOG_OBJECT (self,
+ "discard empty buffer as DTX is enabled: %" GST_PTR_FORMAT, buffer);
+ gst_buffer_unref (buffer);
+ return GST_FLOW_OK;
+ }
+
pts = GST_BUFFER_PTS (buffer);
dts = GST_BUFFER_DTS (buffer);
duration = GST_BUFFER_DURATION (buffer);
diff --git a/gst/rtp/gstrtpopuspay.h b/gst/rtp/gstrtpopuspay.h
index e21bbe3c3..c7dbab10d 100644
--- a/gst/rtp/gstrtpopuspay.h
+++ b/gst/rtp/gstrtpopuspay.h
@@ -44,6 +44,8 @@ typedef struct _GstRtpOPUSPayClass GstRtpOPUSPayClass;
struct _GstRtpOPUSPay
{
GstRTPBasePayload payload;
+
+ gboolean dtx;
};
struct _GstRtpOPUSPayClass