Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@CoreyCole
Last active June 9, 2020 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CoreyCole/a54ec48fd145066818948b4938ffdbb3 to your computer and use it in GitHub Desktop.
Save CoreyCole/a54ec48fd145066818948b4938ffdbb3 to your computer and use it in GitHub Desktop.
static void
handle_media_stream (GstPad * pad, GstElement * pipe, const char *convert_name,
const char *sink_name)
{
GstPad *qpad, *rtp_sink, *rtp_src, *rtcp_src, *rtp_udp_sink, *rtcp_udp_sink;
GstElement *q, *conv, *resample, *opusenc, *rtpopuspay, *rtpbin, *rtp_udpsink, *rtcp_udpsink;
GstPadLinkReturn ret;
gchar *rtpopuspay_string, *rtp_udpsink_string, *rtcp_udpsink_string;
g_print ("Trying to handle stream with %s ! %s", convert_name, sink_name);
if (g_strcmp0 (convert_name, "audioconvert") != 0) {
g_printerr ("peer video input not supported");
return;
}
// data is queued until limits specified by the
// max-size-buffers, max-size-bytes and/or max-size-time properties has been reached.
// Any attempt to push more buffers into the queue will block
// the pushing thread until more space becomes available.
q = gst_element_factory_make ("queue", NULL);
g_assert_nonnull (q);
// converts raw audio buffers between various possible formats.
// It supports integer to float conversion, width/depth conversion,
// signedness and endianness conversion and
// channel transformations (ie. upmixing and downmixing),
// as well as dithering and noise-shaping.
conv = gst_element_factory_make (convert_name, NULL);
g_assert_nonnull (conv);
/* Might also need to resample, so add it just in case.
* Will be a no-op if it's not required. */
// TODO: resample to 16,000 hz ?
resample = gst_element_factory_make ("audioresample", NULL);
g_assert_nonnull (resample);
// encode to opus
opusenc = gst_element_factory_make ("opusenc inband-fec=true bitrate-type=vbr", NULL);
g_assert_nonnull (opusenc);
// Puts Opus audio in RTP packets
rtpopuspay_string = g_strdup_printf ("rtpopuspay pt=%d ssrc=%d", audio_pt, audio_ssrc);
rtpopuspay = gst_element_factory_make (rtpopuspay_string, NULL);
g_assert_nonnull (rtpopuspay);
g_free (rtpopuspay_string);
// bin for forwarding RTP packets
rtpbin = gst_element_factory_make ("rtpbin", NULL);
g_assert_nonnull (rtpbin);
gst_bin_add_many (GST_BIN (pipe), q, conv, resample, opusenc, rtpopuspay, rtpbin, NULL);
gst_element_sync_state_with_parent (q);
gst_element_sync_state_with_parent (conv);
gst_element_sync_state_with_parent (resample);
gst_element_sync_state_with_parent (opusenc);
gst_element_sync_state_with_parent (rtpopuspay);
gst_element_sync_state_with_parent (rtpbin);
rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_1");
gst_element_link_many (q, conv, resample, opusenc, rtpopuspay, rtp_sink, NULL);
// create pad for beginning of chain created above
qpad = gst_element_get_static_pad (q, "sink");
ret = gst_pad_link (pad, qpad);
g_assert_cmphex (ret, ==, GST_PAD_LINK_OK);
// create udpsinks for RTP and RTCP
rtp_udpsink_string = g_strdup_printf ("udpsink host=%s port=%s", audio_transport_ip, audio_transport_rtp_port);
rtp_udpsink = gst_element_factory_make (rtp_udpsink_string, NULL);
g_assert_nonnull (rtp_udpsink);
g_free (rtp_udpsink_string);
rtcp_udpsink_string = g_strdup_printf ("udpsink host=%s port=%s sync=false async=false", audio_transport_ip, audio_transport_rtcp_port);
rtcp_udpsink = gst_element_factory_make (rtcp_udpsink_string, NULL);
g_assert_nonnull (rtcp_udpsink);
g_free (rtcp_udpsink_string);
gst_bin_add_many (GST_BIN (pipe), rtp_udpsink, rtcp_udpsink, NULL);
gst_element_sync_state_with_parent (rtp_udpsink);
gst_element_sync_state_with_parent (rtcp_udpsink);
// send_rtp_src_1 created when send_rtp_sink_1 was requested
rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_1");
// need to request send_rtcp_src_1
rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_1");
// link the RTP and RTCP pads
rtp_udp_sink = gst_element_get_static_pad (rtp_udpsink, "sink");
rtcp_udp_sink = gst_element_get_static_pad (rtcp_udpsink, "sink");
ret = gst_pad_link (rtp_src, rtp_udp_sink);
g_assert_cmphex (ret, ==, GST_PAD_LINK_OK);
ret = gst_pad_link (rtcp_src, rtcp_udp_sink);
g_assert_cmphex (ret, ==, GST_PAD_LINK_OK);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment