Enhance error handling in FrameGrabber destructor, improve connection logic in NetworkStream, and update stream protocols in NetworkToolkit. Refactor Stream and VideoStreamer for better failure logging and termination handling. Modify UserInterfaceManager to clear new panel on reload.

This commit is contained in:
brunoherbelin
2025-11-09 19:55:28 +01:00
parent 08114e2cbe
commit 2f7bd3a3d1
7 changed files with 32 additions and 24 deletions

View File

@@ -312,6 +312,9 @@ FrameGrabber::~FrameGrabber()
gst_object_unref (timer_);
if (pipeline_ != nullptr) {
// ignore errors on ending
gst_bus_set_flushing(gst_element_get_bus(pipeline_), true);
// force pipeline stop
GstState state = GST_STATE_NULL;
gst_element_set_state (pipeline_, state);
gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE);
@@ -438,7 +441,7 @@ GstBusSyncReply FrameGrabber::signal_handler(GstBus *, GstMessage *msg, gpointer
// inform user
GError *error;
gst_message_parse_error(msg, &error, NULL);
Log::Warning("FrameGrabber %s : %s",
Log::Warning("FrameGrabber Error %s : %s",
std::to_string(reinterpret_cast<FrameGrabber *>(ptr)->id()).c_str(),
error->message);
g_error_free(error);

View File

@@ -115,8 +115,10 @@ void wait_for_stream_(UdpListeningReceiveSocket *receiver)
void NetworkStream::connect(const std::string &nameconnection)
{
// start fresh
if (connected())
if (connected()) {
std::this_thread::sleep_for (std::chrono::milliseconds(80));
disconnect();
}
received_config_ = false;
@@ -243,21 +245,22 @@ void NetworkStream::update()
// make sure the shared memory socket exists
if (config_.protocol == NetworkToolkit::SHM_RAW) {
// for shared memory, the parameter is a file location in settings
parameter = SystemToolkit::full_filename(SystemToolkit::temp_path(), "shm") + parameter;
std::string shm_file = SystemToolkit::full_filename(SystemToolkit::temp_path(), "shm") + parameter;
// try few times to see if file exists and wait 20ms each time
for(int trial = 0; trial < 5; trial ++){
if ( SystemToolkit::file_exists(parameter))
for(int trial = 0; trial < 50; trial ++){
if ( SystemToolkit::file_exists(shm_file))
break;
std::this_thread::sleep_for (std::chrono::milliseconds(20));
std::this_thread::sleep_for (std::chrono::milliseconds(80));
}
// failed to find the shm socket file: try to reconnect
if (!SystemToolkit::file_exists(parameter)) {
if ( !SystemToolkit::file_exists(shm_file)) {
failed_ = true;
Log::Warning("Cannot connect to %s with shared memory: reverting to UDP.", streamer_.name.c_str());
Log::Warning("Cannot connect to %s with shared memory: reverting to UDP.", shm_file.c_str());
// quickly disconnect and re-connect
connect( streamer_.name );
}
parameter = "\"" + parameter + "\"";
else
parameter = "\"" + shm_file + "\"";
}
// if not disconnected : create pipeline and open

View File

@@ -98,14 +98,14 @@ const std::vector<std::string> NetworkToolkit::stream_send_pipeline {
"video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=10 ! rtpvrawpay ! application/x-rtp,sampling=RGB ! udpsink name=sink",
"video/x-raw, format=NV12, framerate=30/1 ! queue max-size-buffers=10 ! jpegenc ! rtpjpegpay ! udpsink name=sink",
"video/x-raw, format=NV12, framerate=30/1 ! queue max-size-buffers=10 ! x264enc tune=\"zerolatency\" pass=4 quantizer=22 speed-preset=2 ! h264parse ! rtph264pay aggregate-mode=1 ! udpsink name=sink",
"video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=10 ! shmsink buffer-time=100000 wait-for-connection=true name=sink"
"video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=10 ! shmsink buffer-time=-1 wait-for-connection=true name=sink"
};
const std::vector<std::string> NetworkToolkit::stream_receive_pipeline {
"udpsrc port=XXXX caps=\"application/x-rtp,media=(string)video,encoding-name=(string)RAW,sampling=(string)RGB,width=(string)WWWW,height=(string)HHHH\" ! rtpvrawdepay ! queue max-size-buffers=10",
"udpsrc port=XXXX caps=\"application/x-rtp,media=(string)video,encoding-name=(string)RAW,sampling=(string)RGB,width=(string)WWWW,height=(string)HHHH\" ! rtpvrawdepay ! queue ",
"udpsrc port=XXXX caps=\"application/x-rtp,media=(string)video,encoding-name=(string)JPEG\" ! queue ! rtpjpegdepay ! decodebin",
"udpsrc port=XXXX caps=\"application/x-rtp,media=(string)video,encoding-name=(string)H264\" ! queue ! rtph264depay ! h264parse ! decodebin",
"shmsrc socket-path=XXXX ! video/x-raw, format=RGB, framerate=30/1 ! queue max-size-buffers=10",
"shmsrc socket-path=XXXX is-live=true ! video/x-raw, format=RGB, framerate=30/1 ! queue ",
};
const std::vector< std::pair<std::string, std::string> > NetworkToolkit::stream_h264_send_pipeline {

View File

@@ -20,11 +20,11 @@ namespace NetworkToolkit
{
typedef enum {
UDP_RAW = 0,
UDP_JPEG,
UDP_H264,
SHM_RAW,
DEFAULT
UDP_RAW = 0,
UDP_JPEG = 1,
UDP_H264 = 2,
SHM_RAW = 3,
DEFAULT = 4
} StreamProtocol;
extern const char* stream_protocol_label[DEFAULT];

View File

@@ -321,7 +321,7 @@ void Stream::execute_open()
live_ = false;
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
if (ret == GST_STATE_CHANGE_FAILURE) {
fail(std::string("Could not open ") + description_);
fail(std::string("Could not open '") + description_ + "'");
return;
}
else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
@@ -355,7 +355,7 @@ void Stream::execute_open()
void Stream::fail(const std::string &message)
{
log_ = message;
Log::Warning("Stream %s %s.", std::to_string(id_).c_str(), log_.c_str() );
Log::Warning("Stream %s failed: %s.", std::to_string(id_).c_str(), log_.c_str() );
failed_ = true;
}

View File

@@ -491,6 +491,10 @@ void VideoStreamer::terminate()
// send EOS
gst_app_src_end_of_stream (src_);
// force finished
endofstream_ = true;
active_ = false;
// make sure the shared memory socket is deleted
if (config_.protocol == NetworkToolkit::SHM_RAW) {
std::string path = SystemToolkit::full_filename(SystemToolkit::temp_path(), "shm");
@@ -510,10 +514,6 @@ void VideoStreamer::stop ()
// inform streaming manager to remove myself
// NB: will not be effective if called inside a locked streamers_lock_
Streaming::manager().removeStream(this);
// force finished
endofstream_ = true;
active_ = false;
}
std::string VideoStreamer::info(bool extended) const

View File

@@ -4471,8 +4471,10 @@ void Navigator::RenderNewPannel(const ImVec2 &iconsize)
ICON_FA_CARET_RIGHT " webcams or frame grabbers\n"
ICON_FA_CARET_RIGHT " vimix Peer-to-peer in local network.");
ImGui::SameLine();
if (ImGuiToolkit::IconButton(5, 15, "Reload list"))
if (ImGuiToolkit::IconButton(5, 15, "Reload list")) {
Device::manager().reload();
clearNewPannel();
}
ImGui::Spacing();
if (custom_connected) {