diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index 15c2187..51ecbc8 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -20,6 +20,7 @@ #include "SessionSource.h" #include "PatternSource.h" #include "DeviceSource.h" +#include "NetworkSource.h" #include "Settings.h" #include "Mixer.h" #include "ActionManager.h" @@ -532,3 +533,13 @@ void ImGuiVisitor::visit (DeviceSource& s) } } +void ImGuiVisitor::visit (NetworkSource& s) +{ + ImGuiToolkit::Icon(s.icon().x, s.icon().y); + ImGui::SameLine(0, 10); + ImGui::Text("Network connection"); + + ImGui::Text("Connected to %s", s.connection().c_str()); + +} + diff --git a/ImGuiVisitor.h b/ImGuiVisitor.h index 0f2dac1..1508169 100644 --- a/ImGuiVisitor.h +++ b/ImGuiVisitor.h @@ -29,6 +29,7 @@ public: void visit (CloneSource& s) override; void visit (PatternSource& s) override; void visit (DeviceSource& s) override; + void visit (NetworkSource& s) override; }; #endif // IMGUIVISITOR_H diff --git a/NetworkSource.cpp b/NetworkSource.cpp index b8cd6fa..7960285 100644 --- a/NetworkSource.cpp +++ b/NetworkSource.cpp @@ -172,32 +172,32 @@ void NetworkStream::update() receiver_->AsynchronousBreak(); #ifdef NETWORK_DEBUG - Log::Info("Creating Network Stream %d %d x %d", config_.port, config_.width, config_.height); + Log::Info("Creating Network Stream %d (%d x %d)", config_.port, config_.width, config_.height); #endif // build the pipeline depending on stream info std::ostringstream pipeline; - if (config_.protocol == NetworkToolkit::UDP_JPEG || config_.protocol == NetworkToolkit::UDP_H264) { - - pipeline << "udpsrc port=" << config_.port; - } - else if (config_.protocol == NetworkToolkit::TCP_JPEG || config_.protocol == NetworkToolkit::TCP_H264) { - - pipeline << "tcpclientsrc timeout=1 port=" << config_.port; - } - else if (config_.protocol == NetworkToolkit::SHM_RAW) { + // get generic pipeline string + std::string pipelinestring = NetworkToolkit::protocol_receive_pipeline[config_.protocol]; + // find placeholder for PORT + int xxxx = pipelinestring.find("XXXX"); + // keep beginning of pipeline + pipeline << pipelinestring.substr(0, xxxx); + // Replace 'XXXX' + if (config_.protocol == NetworkToolkit::SHM_RAW) { std::string path = SystemToolkit::full_filename(SystemToolkit::settings_path(), "shm"); path += std::to_string(config_.port); - pipeline << "shmsrc is-live=true socket-path=" << path; - // TODO rename SHM socket "shm_PORT" + pipeline << path; } - - pipeline << NetworkToolkit::protocol_receive_pipeline[config_.protocol]; + else + pipeline << config_.port; + // keep ending of pipeline + pipeline << pipelinestring.substr(xxxx + 4); + // add a videoconverter pipeline << " ! videoconvert"; // open the pipeline with generic stream class Stream::open(pipeline.str(), config_.width, config_.height); - } } diff --git a/NetworkToolkit.cpp b/NetworkToolkit.cpp index e5e2f29..5a2d2eb 100644 --- a/NetworkToolkit.cpp +++ b/NetworkToolkit.cpp @@ -1,45 +1,20 @@ -#include -#include +#include + #include -#include // std::count #include #include -#include #include -//#include +// TODO OSX implementation +#include + +// OSC IP gethostbyname #include "ip/NetworkingUtils.h" #include "NetworkToolkit.h" -const char* NetworkToolkit::protocol_name[NetworkToolkit::DEFAULT] = { - "TCP Broadcast JPEG", - "TCP Broadcast H264", - "Shared Memory" -}; - -const std::vector NetworkToolkit::protocol_send_pipeline { - - "video/x-raw, format=I420, framerate=30/1 ! queue max-size-buffers=3 ! jpegenc ! rtpjpegpay ! udpsink name=sink", - "video/x-raw, format=I420, framerate=30/1 ! queue max-size-buffers=3 ! x264enc tune=\"zerolatency\" threads=2 ! rtph264pay ! udpsink name=sink", - "video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=3 ! shmsink buffer-time=100000 name=sink", - "video/x-raw, format=I420 ! queue max-size-buffers=3 ! jpegenc ! rtpjpegpay ! rtpstreampay ! tcpserversink name=sink", - "video/x-raw, format=I420 ! queue max-size-buffers=3 ! x264enc tune=\"zerolatency\" threads=2 ! rtph264pay ! rtpstreampay ! tcpserversink name=sink", -}; - - -const std::vector NetworkToolkit::protocol_receive_pipeline { - - " ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec", - " ! application/x-rtp,media=video,encoding-name=H264,payload=96,clock-rate=90000 ! rtph264depay ! avdec_h264", - " ! video/x-raw, format=RGB, framerate=30/1", - " ! application/x-rtp-stream,media=video,encoding-name=JPEG,payload=26 ! rtpstreamdepay ! rtpjpegdepay ! jpegdec", - " ! application/x-rtp-stream,media=video,encoding-name=H264,payload=96,clock-rate=90000 ! rtpstreamdepay ! rtph264depay ! avdec_h264", -}; - - /*** * * TCP Server JPEG : broadcast @@ -82,6 +57,32 @@ const std::vector NetworkToolkit::protocol_receive_pipeline { * * */ +const char* NetworkToolkit::protocol_name[NetworkToolkit::DEFAULT] = { + "Shared Memory", + "UDP Broadcast JPEG", + "UDP Broadcast H264", + "TCP Broadcast JPEG", + "TCP Broadcast H264" +}; + +const std::vector NetworkToolkit::protocol_send_pipeline { + + "video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=3 ! shmsink buffer-time=100000 name=sink", + "video/x-raw, format=I420, framerate=30/1 ! queue max-size-buffers=3 ! jpegenc ! rtpjpegpay ! udpsink name=sink", + "video/x-raw, format=I420, framerate=30/1 ! queue max-size-buffers=3 ! x264enc tune=\"zerolatency\" threads=2 ! rtph264pay ! udpsink name=sink", + "video/x-raw, format=I420 ! queue max-size-buffers=3 ! jpegenc ! rtpjpegpay ! rtpstreampay ! tcpserversink name=sink", + "video/x-raw, format=I420 ! queue max-size-buffers=3 ! x264enc tune=\"zerolatency\" threads=2 ! rtph264pay ! rtpstreampay ! tcpserversink name=sink" +}; + +const std::vector NetworkToolkit::protocol_receive_pipeline { + + "shmsrc is-live=true socket-path=XXXX ! queue max-size-buffers=3 ! video/x-raw, format=RGB, framerate=30/1", + "udpsrc port=XXXX ! queue max-size-buffers=3 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec", + "udpsrc port=XXXX ! queue max-size-buffers=3 ! application/x-rtp,media=video,encoding-name=H264,payload=96,clock-rate=90000 ! rtph264depay ! avdec_h264", + "tcpclientsrc timeout=1 port=XXXX ! queue max-size-buffers=3 ! application/x-rtp-stream,media=video,encoding-name=JPEG,payload=26 ! rtpstreamdepay ! rtpjpegdepay ! jpegdec", + "tcpclientsrc timeout=1 port=XXXX ! queue max-size-buffers=3 ! application/x-rtp-stream,media=video,encoding-name=H264,payload=96,clock-rate=90000 ! rtpstreamdepay ! rtph264depay ! avdec_h264" +}; + std::vector ipstrings; std::vector iplongs; diff --git a/NetworkToolkit.h b/NetworkToolkit.h index f29e516..20c30b7 100644 --- a/NetworkToolkit.h +++ b/NetworkToolkit.h @@ -22,9 +22,9 @@ namespace NetworkToolkit { typedef enum { - UDP_JPEG = 0, + SHM_RAW = 0, + UDP_JPEG, UDP_H264, - SHM_RAW, TCP_JPEG, TCP_H264, DEFAULT diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 8748609..43426cf 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -11,6 +11,7 @@ #include "StreamSource.h" #include "PatternSource.h" #include "DeviceSource.h" +#include "NetworkSource.h" #include "Session.h" #include "ImageShader.h" #include "ImageProcessingShader.h" @@ -527,4 +528,14 @@ void SessionLoader::visit (DeviceSource& s) } +void SessionLoader::visit (NetworkSource& s) +{ + std::string connect = std::string ( xmlCurrent_->Attribute("connection") ); + + // change only if different device + if ( connect != s.connection() ) + s.setConnection(connect); +} + + diff --git a/SessionCreator.h b/SessionCreator.h index 877d4f8..32d5998 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -49,6 +49,7 @@ public: void visit (SessionSource& s) override; void visit (PatternSource& s) override; void visit (DeviceSource& s) override; + void visit (NetworkSource& s) override; protected: tinyxml2::XMLElement *xmlCurrent_; diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index 8a2aefa..3dab26b 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -8,6 +8,7 @@ #include "SessionSource.h" #include "PatternSource.h" #include "DeviceSource.h" +#include "NetworkSource.h" #include "ImageShader.h" #include "ImageProcessingShader.h" #include "MediaPlayer.h" @@ -402,3 +403,9 @@ void SessionVisitor::visit (DeviceSource& s) xmlCurrent_->SetAttribute("type", "DeviceSource"); xmlCurrent_->SetAttribute("device", s.device().c_str() ); } + +void SessionVisitor::visit (NetworkSource& s) +{ + xmlCurrent_->SetAttribute("type", "NetworkSource"); + xmlCurrent_->SetAttribute("connection", s.connection().c_str() ); +} diff --git a/SessionVisitor.h b/SessionVisitor.h index 9bc7440..39e343c 100644 --- a/SessionVisitor.h +++ b/SessionVisitor.h @@ -48,6 +48,7 @@ public: void visit (CloneSource& s) override; void visit (PatternSource& s) override; void visit (DeviceSource& s) override; + void visit (NetworkSource& s) override; static tinyxml2::XMLElement *NodeToXML(Node &n, tinyxml2::XMLDocument *doc); }; diff --git a/Streamer.cpp b/Streamer.cpp index ecdfa7b..6598ffc 100644 --- a/Streamer.cpp +++ b/Streamer.cpp @@ -183,7 +183,7 @@ void Streaming::addStream(const std::string &sender, int reply_to) else { conf.protocol = NetworkToolkit::UDP_JPEG; } -// conf.protocol = NetworkToolkit::UDP_JPEG; + conf.protocol = NetworkToolkit::UDP_JPEG; // build OSC message char buffer[IP_MTU_SIZE]; @@ -269,11 +269,12 @@ void VideoStreamer::addFrame (FrameBuffer *frame_buffer, float dt) glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_[0]); glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ); - // create a gstreamer pipeline - std::string description = "appsrc name=src ! videoconvert ! "; - + // prevent eroneous protocol values if (config_.protocol < 0 || config_.protocol >= NetworkToolkit::DEFAULT) config_.protocol = NetworkToolkit::UDP_JPEG; + + // create a gstreamer pipeline + std::string description = "appsrc name=src ! videoconvert ! "; description += NetworkToolkit::protocol_send_pipeline[config_.protocol]; // parse pipeline descriptor diff --git a/Visitor.h b/Visitor.h index be5c834..1366244 100644 --- a/Visitor.h +++ b/Visitor.h @@ -33,6 +33,7 @@ class GenericStreamSource; class SessionSource; class RenderSource; class CloneSource; +class NetworkSource; // Declares the interface for the visitors class Visitor { @@ -66,6 +67,7 @@ public: // utility virtual void visit (Source&) {} virtual void visit (MediaSource&) {} + virtual void visit (NetworkSource&) {} virtual void visit (GenericStreamSource&) {} virtual void visit (DeviceSource&) {} virtual void visit (PatternSource&) {}