diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.com> | 2021-03-31 11:18:30 +0200 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.com> | 2021-04-26 15:25:56 +0200 |
commit | 41ba8c1b00f5ad5f27c37b97ddee196d9d6e6d6a (patch) | |
tree | bb1e1d639d1422ca682201ffa517b183ee79952e /gst | |
parent | a0067316e741e20e1ecbb01b3a3005fb64952eb7 (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.c | 70 | ||||
-rw-r--r-- | gst/rtp/gstrtpopuspay.h | 2 |
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 |