+static guint16
+pull_rtp_buffer (GstHarness * h)
+{
+ gint16 seq;
+ GstBuffer *buf;
+ GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+
+ buf = gst_harness_try_pull (h);
+ fail_unless (buf);
+
+ fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
+ seq = gst_rtp_buffer_get_seq (&rtp);
+ gst_rtp_buffer_unmap (&rtp);
+
+ gst_buffer_unref (buf);
+ return seq;
+}
+
+static void
+test_rtp_opus_dtx (gboolean dtx)
+{
+ GstHarness *h;
+ GstBuffer *buf;
+ /* generated with a muted mic using:
+ * gst-launch-1.0 pulsesrc ! opusenc dtx=true bitrate-type=vbr ! fakesink silent=false dump=true -v
+ */
+ static const guint8 opus_empty[] = { 0xf8 };
+ static const guint8 opus_frame[] = { 0xf8, 0xff, 0xfe };
+ guint16 seq, expected_seq;
+
+ h = gst_harness_new_parse ("rtpopuspay");
+ fail_unless (h);
+
+ gst_harness_set (h, "rtpopuspay", "dtx", dtx, NULL);
+
+ gst_harness_set_caps_str (h,
+ "audio/x-opus, rate=48000, channels=1, channel-mapping-family=0",
+ "application/x-rtp, media=audio, clock-rate=48000, encoding-name=OPUS, sprop-stereo=(string)0, encoding-params=(string)2, sprop-maxcapturerate=(string)48000, payload=96");
+
+ /* push first opus frame */
+ buf =
+ gst_buffer_new_wrapped (g_memdup (opus_frame, sizeof (opus_frame)),
+ sizeof (opus_frame));
+ fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
+ seq = pull_rtp_buffer (h);
+ expected_seq = seq + 1;
+
+ /* push empty frame */
+ buf =
+ gst_buffer_new_wrapped (g_memdup (opus_empty, sizeof (opus_empty)),
+ sizeof (opus_empty));
+ fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
+ if (dtx) {
+ /* buffer is not transmitted if dtx is enabled */
+ buf = gst_harness_try_pull (h);
+ fail_if (buf);
+ } else {
+ seq = pull_rtp_buffer (h);
+ fail_unless_equals_int (seq, expected_seq);
+ expected_seq++;
+ }
+
+ /* push second opus frame */
+ buf =
+ gst_buffer_new_wrapped (g_memdup (opus_frame, sizeof (opus_frame)),
+ sizeof (opus_frame));
+ fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
+ seq = pull_rtp_buffer (h);
+ fail_unless_equals_int (seq, expected_seq);
+
+ gst_harness_teardown (h);
+}
+
+GST_START_TEST (rtp_opus_dtx_disabled)
+{
+ test_rtp_opus_dtx (FALSE);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (rtp_opus_dtx_enabled)
+{
+ test_rtp_opus_dtx (TRUE);
+}
+
+GST_END_TEST;
+