mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 15:30:00 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user