From ffc72a96fbfc55280a11f670666802d31ec93ea4 Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Fri, 2 Nov 2018 21:15:44 -0400 Subject: [PATCH 1/6] Added capability to read from a udpsrc. To generalize it, possibly similarly to gscam. --- audio_capture/launch/capture_udp.launch | 25 ++++++++ audio_capture/src/audio_capture.cpp | 78 +++++++++++++++++++------ 2 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 audio_capture/launch/capture_udp.launch diff --git a/audio_capture/launch/capture_udp.launch b/audio_capture/launch/capture_udp.launch new file mode 100644 index 00000000..64d470fc --- /dev/null +++ b/audio_capture/launch/capture_udp.launch @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index e5d6ee5f..cd9c5e47 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -16,7 +16,7 @@ namespace audio_transport { _bitrate = 192; - std::string dst_type; + std::string dst_type, source_type; // Need to encoding or publish raw wave data ros::param::param("~format", _format, "mp3"); @@ -33,7 +33,9 @@ namespace audio_transport ros::param::param("~dst", dst_type, "appsink"); // The source of the audio - //ros::param::param("~src", source_type, "alsasrc"); + ros::param::param("~src", source_type, "alsasrc"); + int port; + ros::param::param("~port", port, 5603); std::string device; ros::param::param("~device", device, ""); @@ -63,30 +65,60 @@ namespace audio_transport g_object_set( G_OBJECT(_sink), "location", dst_type.c_str(), NULL); } - _source = gst_element_factory_make("alsasrc", "source"); - // if device isn't specified, it will use the default which is - // the alsa default source. - // A valid device will be of the foram hw:0,0 with other numbers - // than 0 and 0 as are available. - if (device != "") + _source = gst_element_factory_make(source_type.c_str(), "source"); + + if (source_type == "udpsrc") { - // ghcar *gst_device = device.c_str(); - g_object_set(G_OBJECT(_source), "device", device.c_str(), NULL); + g_object_set (G_OBJECT (_source), "port", port, NULL); + _filter = gst_element_factory_make("capsfilter", "filter"); + { + GstCaps *caps; + caps = gst_caps_new_simple("application/x-rtp", + "media", G_TYPE_STRING, "audio", + "clock-rate", G_TYPE_INT, 44100, + "width", G_TYPE_INT, 16, + "height", G_TYPE_INT, 16, + "encoding-name", G_TYPE_STRING, "L16", + "encoding-params", G_TYPE_STRING, "1", + "channels", G_TYPE_INT, 1, + "channel-positions", G_TYPE_INT, 1, + "payload", G_TYPE_INT, 96, + NULL); + g_object_set( G_OBJECT(_filter), "caps", caps, NULL); + gst_caps_unref(caps); + } + _demux = gst_element_factory_make ("rtpL16depay", "rtpdepay"); } - - _filter = gst_element_factory_make("capsfilter", "filter"); + else { - GstCaps *caps; - caps = gst_caps_new_simple("audio/x-raw", + // if device isn't specified, it will use the default which is + // the alsa default source. + // A valid device will be of the foram hw:0,0 with other numbers + // than 0 and 0 as are available. + if (device != "") + { + // ghcar *gst_device = device.c_str(); + g_object_set(G_OBJECT(_source), "device", device.c_str(), NULL); + } + _filter = gst_element_factory_make("capsfilter", "filter"); + { + GstCaps *caps; + caps = gst_caps_new_simple("audio/x-raw", // "channels", G_TYPE_INT, _channels, // "depth", G_TYPE_INT, _depth, "rate", G_TYPE_INT, _sample_rate, // "signed", G_TYPE_BOOLEAN, TRUE, NULL); - g_object_set( G_OBJECT(_filter), "caps", caps, NULL); - gst_caps_unref(caps); + g_object_set( G_OBJECT(_filter), "caps", caps, NULL); + gst_caps_unref(caps); + } + _demux = NULL; } + + + + _convert = gst_element_factory_make("audioconvert", "convert"); if (!_convert) { ROS_ERROR_STREAM("Failed to create audioconvert element"); @@ -104,8 +136,16 @@ namespace audio_transport g_object_set( G_OBJECT(_encode), "quality", 2.0, NULL); g_object_set( G_OBJECT(_encode), "bitrate", _bitrate, NULL); - gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _convert, _encode, _sink, NULL); - link_ok = gst_element_link_many(_source, _filter, _convert, _encode, _sink, NULL); + if (_demux == NULL) + { + gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _convert, _encode, _sink, NULL); + link_ok = gst_element_link_many(_source, _filter, _convert, _encode, _sink, NULL); + } + else + { + gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _demux, _convert, _encode, _sink, NULL); + link_ok = gst_element_link_many(_source, _filter, _demux, _convert, _encode, _sink, NULL); + } } else if (_format == "wave") { GstCaps *caps; caps = gst_caps_new_simple("audio/x-raw", @@ -209,7 +249,7 @@ namespace audio_transport boost::thread _gst_thread; - GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode; + GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode, *_demux; GstBus *_bus; int _bitrate, _channels, _depth, _sample_rate; GMainLoop *_loop; From d564c9712bc9dd36435b2f85b96064b4c91bda24 Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Thu, 30 May 2019 21:45:09 -0400 Subject: [PATCH 2/6] Clean up of audio_capture and more general implementation for depay and handling of non-supported modes. --- audio_capture/launch/capture_udp.launch | 4 ++ audio_capture/src/audio_capture.cpp | 54 ++++++++++++++----------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/audio_capture/launch/capture_udp.launch b/audio_capture/launch/capture_udp.launch index 64d470fc..8fbc0d56 100644 --- a/audio_capture/launch/capture_udp.launch +++ b/audio_capture/launch/capture_udp.launch @@ -9,6 +9,8 @@ + + @@ -19,6 +21,8 @@ + + diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index cd9c5e47..93688aad 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -14,8 +14,6 @@ namespace audio_transport public: RosGstCapture() { - _bitrate = 192; - std::string dst_type, source_type; // Need to encoding or publish raw wave data @@ -34,8 +32,6 @@ namespace audio_transport // The source of the audio ros::param::param("~src", source_type, "alsasrc"); - int port; - ros::param::param("~port", port, 5603); std::string device; ros::param::param("~device", device, ""); @@ -69,27 +65,36 @@ namespace audio_transport if (source_type == "udpsrc") { + int port; + ros::param::param("~port", port, 5603); g_object_set (G_OBJECT (_source), "port", port, NULL); + + std::string depay; + ros::param::param("~depay", depay, "L16"); + _filter = gst_element_factory_make("capsfilter", "filter"); { GstCaps *caps; caps = gst_caps_new_simple("application/x-rtp", - "media", G_TYPE_STRING, "audio", - "clock-rate", G_TYPE_INT, 44100, - "width", G_TYPE_INT, 16, - "height", G_TYPE_INT, 16, - "encoding-name", G_TYPE_STRING, "L16", - "encoding-params", G_TYPE_STRING, "1", - "channels", G_TYPE_INT, 1, - "channel-positions", G_TYPE_INT, 1, - "payload", G_TYPE_INT, 96, + "media", G_TYPE_STRING, "audio", + "clock-rate", G_TYPE_INT, _sample_rate, + "encoding-name", G_TYPE_STRING, depay.c_str(), + "channels", G_TYPE_INT, _channels, NULL); g_object_set( G_OBJECT(_filter), "caps", caps, NULL); gst_caps_unref(caps); } - _demux = gst_element_factory_make ("rtpL16depay", "rtpdepay"); + if (depay == "L16") + { + _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); // TODO: more general to use any decoder. + } + else + { + ROS_ERROR_STREAM("Depay currently not supported, it must be \"L16\""); + exitOnMainThread(1); + } } - else + else if (source_type == "alsasrc") { // if device isn't specified, it will use the default which is // the alsa default source. @@ -112,12 +117,13 @@ namespace audio_transport g_object_set( G_OBJECT(_filter), "caps", caps, NULL); gst_caps_unref(caps); } - _demux = NULL; + _depay = NULL; + } + else + { + ROS_ERROR_STREAM("Source currently not supported"); + exitOnMainThread(1); } - - - - _convert = gst_element_factory_make("audioconvert", "convert"); if (!_convert) { @@ -136,15 +142,15 @@ namespace audio_transport g_object_set( G_OBJECT(_encode), "quality", 2.0, NULL); g_object_set( G_OBJECT(_encode), "bitrate", _bitrate, NULL); - if (_demux == NULL) + if (_depay== NULL) { gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _convert, _encode, _sink, NULL); link_ok = gst_element_link_many(_source, _filter, _convert, _encode, _sink, NULL); } else { - gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _demux, _convert, _encode, _sink, NULL); - link_ok = gst_element_link_many(_source, _filter, _demux, _convert, _encode, _sink, NULL); + gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _depay, _convert, _encode, _sink, NULL); + link_ok = gst_element_link_many(_source, _filter, _depay, _convert, _encode, _sink, NULL); } } else if (_format == "wave") { GstCaps *caps; @@ -249,7 +255,7 @@ namespace audio_transport boost::thread _gst_thread; - GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode, *_demux; + GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode, *_depay; GstBus *_bus; int _bitrate, _channels, _depth, _sample_rate; GMainLoop *_loop; From 088b50fd9d7d26ba522163bd78e295c420ec8996 Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Thu, 30 May 2019 21:58:35 -0400 Subject: [PATCH 3/6] Cleanup of redundant code. --- audio_capture/src/audio_capture.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index 93688aad..6ad974cd 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -63,6 +63,9 @@ namespace audio_transport _source = gst_element_factory_make(source_type.c_str(), "source"); + _filter = gst_element_factory_make("capsfilter", "filter"); + + GstCaps *caps; if (source_type == "udpsrc") { int port; @@ -72,18 +75,13 @@ namespace audio_transport std::string depay; ros::param::param("~depay", depay, "L16"); - _filter = gst_element_factory_make("capsfilter", "filter"); - { - GstCaps *caps; - caps = gst_caps_new_simple("application/x-rtp", + caps = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, "audio", "clock-rate", G_TYPE_INT, _sample_rate, "encoding-name", G_TYPE_STRING, depay.c_str(), "channels", G_TYPE_INT, _channels, NULL); - g_object_set( G_OBJECT(_filter), "caps", caps, NULL); - gst_caps_unref(caps); - } + if (depay == "L16") { _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); // TODO: more general to use any decoder. @@ -105,18 +103,14 @@ namespace audio_transport // ghcar *gst_device = device.c_str(); g_object_set(G_OBJECT(_source), "device", device.c_str(), NULL); } - _filter = gst_element_factory_make("capsfilter", "filter"); - { - GstCaps *caps; - caps = gst_caps_new_simple("audio/x-raw", + + caps = gst_caps_new_simple("audio/x-raw", // "channels", G_TYPE_INT, _channels, // "depth", G_TYPE_INT, _depth, "rate", G_TYPE_INT, _sample_rate, // "signed", G_TYPE_BOOLEAN, TRUE, NULL); - g_object_set( G_OBJECT(_filter), "caps", caps, NULL); - gst_caps_unref(caps); - } + _depay = NULL; } else @@ -124,6 +118,8 @@ namespace audio_transport ROS_ERROR_STREAM("Source currently not supported"); exitOnMainThread(1); } + g_object_set( G_OBJECT(_filter), "caps", caps, NULL); + gst_caps_unref(caps); _convert = gst_element_factory_make("audioconvert", "convert"); if (!_convert) { From 440570e8ee67b467c6dafd1fa3636225d7085c51 Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Thu, 30 May 2019 21:45:09 -0400 Subject: [PATCH 4/6] Clean up of audio_capture and more general implementation for depay and handling of non-supported modes. --- audio_capture/launch/capture_udp.launch | 4 ++ audio_capture/src/audio_capture.cpp | 54 ++++++++++++++----------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/audio_capture/launch/capture_udp.launch b/audio_capture/launch/capture_udp.launch index 64d470fc..8fbc0d56 100644 --- a/audio_capture/launch/capture_udp.launch +++ b/audio_capture/launch/capture_udp.launch @@ -9,6 +9,8 @@ + + @@ -19,6 +21,8 @@ + + diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index cd9c5e47..93688aad 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -14,8 +14,6 @@ namespace audio_transport public: RosGstCapture() { - _bitrate = 192; - std::string dst_type, source_type; // Need to encoding or publish raw wave data @@ -34,8 +32,6 @@ namespace audio_transport // The source of the audio ros::param::param("~src", source_type, "alsasrc"); - int port; - ros::param::param("~port", port, 5603); std::string device; ros::param::param("~device", device, ""); @@ -69,27 +65,36 @@ namespace audio_transport if (source_type == "udpsrc") { + int port; + ros::param::param("~port", port, 5603); g_object_set (G_OBJECT (_source), "port", port, NULL); + + std::string depay; + ros::param::param("~depay", depay, "L16"); + _filter = gst_element_factory_make("capsfilter", "filter"); { GstCaps *caps; caps = gst_caps_new_simple("application/x-rtp", - "media", G_TYPE_STRING, "audio", - "clock-rate", G_TYPE_INT, 44100, - "width", G_TYPE_INT, 16, - "height", G_TYPE_INT, 16, - "encoding-name", G_TYPE_STRING, "L16", - "encoding-params", G_TYPE_STRING, "1", - "channels", G_TYPE_INT, 1, - "channel-positions", G_TYPE_INT, 1, - "payload", G_TYPE_INT, 96, + "media", G_TYPE_STRING, "audio", + "clock-rate", G_TYPE_INT, _sample_rate, + "encoding-name", G_TYPE_STRING, depay.c_str(), + "channels", G_TYPE_INT, _channels, NULL); g_object_set( G_OBJECT(_filter), "caps", caps, NULL); gst_caps_unref(caps); } - _demux = gst_element_factory_make ("rtpL16depay", "rtpdepay"); + if (depay == "L16") + { + _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); // TODO: more general to use any decoder. + } + else + { + ROS_ERROR_STREAM("Depay currently not supported, it must be \"L16\""); + exitOnMainThread(1); + } } - else + else if (source_type == "alsasrc") { // if device isn't specified, it will use the default which is // the alsa default source. @@ -112,12 +117,13 @@ namespace audio_transport g_object_set( G_OBJECT(_filter), "caps", caps, NULL); gst_caps_unref(caps); } - _demux = NULL; + _depay = NULL; + } + else + { + ROS_ERROR_STREAM("Source currently not supported"); + exitOnMainThread(1); } - - - - _convert = gst_element_factory_make("audioconvert", "convert"); if (!_convert) { @@ -136,15 +142,15 @@ namespace audio_transport g_object_set( G_OBJECT(_encode), "quality", 2.0, NULL); g_object_set( G_OBJECT(_encode), "bitrate", _bitrate, NULL); - if (_demux == NULL) + if (_depay== NULL) { gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _convert, _encode, _sink, NULL); link_ok = gst_element_link_many(_source, _filter, _convert, _encode, _sink, NULL); } else { - gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _demux, _convert, _encode, _sink, NULL); - link_ok = gst_element_link_many(_source, _filter, _demux, _convert, _encode, _sink, NULL); + gst_bin_add_many( GST_BIN(_pipeline), _source, _filter, _depay, _convert, _encode, _sink, NULL); + link_ok = gst_element_link_many(_source, _filter, _depay, _convert, _encode, _sink, NULL); } } else if (_format == "wave") { GstCaps *caps; @@ -249,7 +255,7 @@ namespace audio_transport boost::thread _gst_thread; - GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode, *_demux; + GstElement *_pipeline, *_source, *_filter, *_sink, *_convert, *_encode, *_depay; GstBus *_bus; int _bitrate, _channels, _depth, _sample_rate; GMainLoop *_loop; From e9771c95fd6f705934ca298780d2466145b92c62 Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Thu, 30 May 2019 21:58:35 -0400 Subject: [PATCH 5/6] Cleanup of redundant code. --- audio_capture/src/audio_capture.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index 93688aad..6ad974cd 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -63,6 +63,9 @@ namespace audio_transport _source = gst_element_factory_make(source_type.c_str(), "source"); + _filter = gst_element_factory_make("capsfilter", "filter"); + + GstCaps *caps; if (source_type == "udpsrc") { int port; @@ -72,18 +75,13 @@ namespace audio_transport std::string depay; ros::param::param("~depay", depay, "L16"); - _filter = gst_element_factory_make("capsfilter", "filter"); - { - GstCaps *caps; - caps = gst_caps_new_simple("application/x-rtp", + caps = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, "audio", "clock-rate", G_TYPE_INT, _sample_rate, "encoding-name", G_TYPE_STRING, depay.c_str(), "channels", G_TYPE_INT, _channels, NULL); - g_object_set( G_OBJECT(_filter), "caps", caps, NULL); - gst_caps_unref(caps); - } + if (depay == "L16") { _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); // TODO: more general to use any decoder. @@ -105,18 +103,14 @@ namespace audio_transport // ghcar *gst_device = device.c_str(); g_object_set(G_OBJECT(_source), "device", device.c_str(), NULL); } - _filter = gst_element_factory_make("capsfilter", "filter"); - { - GstCaps *caps; - caps = gst_caps_new_simple("audio/x-raw", + + caps = gst_caps_new_simple("audio/x-raw", // "channels", G_TYPE_INT, _channels, // "depth", G_TYPE_INT, _depth, "rate", G_TYPE_INT, _sample_rate, // "signed", G_TYPE_BOOLEAN, TRUE, NULL); - g_object_set( G_OBJECT(_filter), "caps", caps, NULL); - gst_caps_unref(caps); - } + _depay = NULL; } else @@ -124,6 +118,8 @@ namespace audio_transport ROS_ERROR_STREAM("Source currently not supported"); exitOnMainThread(1); } + g_object_set( G_OBJECT(_filter), "caps", caps, NULL); + gst_caps_unref(caps); _convert = gst_element_factory_make("audioconvert", "convert"); if (!_convert) { From 9e6595e57ab965e648686df09b82fec6148615ff Mon Sep 17 00:00:00 2001 From: Alberto Quattrini Li Date: Thu, 30 May 2019 22:12:07 -0400 Subject: [PATCH 6/6] Cleanup of a comment. --- audio_capture/src/audio_capture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio_capture/src/audio_capture.cpp b/audio_capture/src/audio_capture.cpp index 6ad974cd..21970099 100644 --- a/audio_capture/src/audio_capture.cpp +++ b/audio_capture/src/audio_capture.cpp @@ -84,7 +84,7 @@ namespace audio_transport if (depay == "L16") { - _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); // TODO: more general to use any decoder. + _depay = gst_element_factory_make ("rtpL16depay", "rtpdepay"); } else {