diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index 1614bc453b..5174679abf 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -193,7 +193,6 @@ src/slic3r/GUI/ObjColorDialog.cpp src/slic3r/GUI/SyncAmsInfoDialog.cpp src/slic3r/GUI/WipeTowerDialog.cpp src/slic3r/GUI/wxExtensions.cpp -src/slic3r/GUI/wxMediaCtrl2.cpp src/slic3r/GUI/WebUserLoginDialog.cpp src/slic3r/GUI/WebGuideDialog.cpp src/slic3r/GUI/KBShortcutsDialog.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index fa09f5d712..3a59504b6e 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -794,8 +794,6 @@ else () list(APPEND SLIC3R_GUI_SOURCES GUI/AVVideoDecoder.cpp GUI/AVVideoDecoder.hpp - GUI/wxMediaCtrl2.cpp - GUI/wxMediaCtrl2.h GUI/wxMediaCtrl3.cpp GUI/wxMediaCtrl3.h ) diff --git a/src/slic3r/GUI/MediaPlayCtrl.h b/src/slic3r/GUI/MediaPlayCtrl.h index 4908a782ca..0a01daefc9 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.h +++ b/src/slic3r/GUI/MediaPlayCtrl.h @@ -8,14 +8,7 @@ #ifndef MediaPlayCtrl_h #define MediaPlayCtrl_h -#define USE_WX_MEDIA_CTRL_2 0 - -#if USE_WX_MEDIA_CTRL_2 -#include "wxMediaCtrl2.h" -#define wxMediaCtrl3 wxMediaCtrl2 -#else #include "wxMediaCtrl3.h" -#endif #include diff --git a/src/slic3r/GUI/wxMediaCtrl2.cpp b/src/slic3r/GUI/wxMediaCtrl2.cpp deleted file mode 100644 index 7500de6626..0000000000 --- a/src/slic3r/GUI/wxMediaCtrl2.cpp +++ /dev/null @@ -1,649 +0,0 @@ -#include "wxMediaCtrl2.h" -#include "libslic3r/Time.hpp" -#include "I18N.hpp" -#include "GUI_App.hpp" -#include "libslic3r/Utils.hpp" -#include -#include -#include "LinuxDisplayBackend.hpp" -#include -#include -#ifdef __WIN32__ -#include -#include -#include -#include -#endif - -#ifdef __LINUX__ -#include "Printer/gstbambusrc.h" -#include // main gstreamer header -#endif - -#if defined(__LINUX__) && defined(__WXGTK__) -#include -#include - -namespace { -bool ensure_gstreamer_initialized_for_liveview() -{ - GError* error = nullptr; - if (!gst_init_check(nullptr, nullptr, &error)) { - BOOST_LOG_TRIVIAL(error) << "wxMediaCtrl2: gst_init_check failed before native Wayland liveview setup" - << (error ? std::string(": ") + error->message : std::string()); - if (error) - g_error_free(error); - return false; - } - - return true; -} - -bool is_gstreamer_feature_available(const char* feature) -{ - if (!ensure_gstreamer_initialized_for_liveview()) - return false; - - GstElementFactory* factory = gst_element_factory_find(feature); - if (!factory) - return false; - - gst_object_unref(factory); - return true; -} - -void set_gstreamer_feature_rank(const char* feature, guint rank) -{ - GstElementFactory* factory = gst_element_factory_find(feature); - if (!factory) - return; - - gst_plugin_feature_set_rank(GST_PLUGIN_FEATURE(factory), rank); - gst_object_unref(factory); -} - -void configure_wayland_gstreamer_liveview_path() -{ - static bool configured = false; - if (configured) - return; - configured = true; - - if (!ensure_gstreamer_initialized_for_liveview()) - return; - - // Prefer software decode for Bambu liveview on Wayland/NVIDIA, where - // zero-copy GL/DMABUF display paths can be fragile. Keep hardware - // decoders available as lower-ranked fallbacks for VAAPI/NVDEC/V4L2-only - // installations instead of passing preflight and then blocking autoplug. - set_gstreamer_feature_rank("avdec_h264", GST_RANK_PRIMARY + 300); - set_gstreamer_feature_rank("openh264dec", GST_RANK_PRIMARY + 100); - set_gstreamer_feature_rank("nvh264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("vaapih264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("vah264dec", GST_RANK_MARGINAL); - set_gstreamer_feature_rank("v4l2h264dec", GST_RANK_MARGINAL); -} -} - -#endif // defined(__LINUX__) && defined(__WXGTK__) - -#ifdef __LINUX__ -extern "C" int gst_bambu_last_error; - -class WXDLLIMPEXP_MEDIA - wxGStreamerMediaBackend : public wxMediaBackendCommonBase -{ -public: - GstElement *m_playbin; // GStreamer media element -}; -#endif - -wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent) -{ -#if defined(__LINUX__) && defined(__WXGTK__) - m_native_wayland = Slic3r::GUI::is_running_on_wayland(); - if (m_native_wayland && is_gstreamer_feature_available("gtksink")) - configure_wayland_gstreamer_liveview_path(); - else if (m_native_wayland) { - m_gtk_sink_error = _L("Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer."); - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: native Wayland liveview disabled because GStreamer gtksink is unavailable"; - } -#endif -#ifdef __WIN32__ - auto hModExe = GetModuleHandle(NULL); - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe; - auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement"); - auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance"); - if (NvOptimusEnablement) { - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: NvOptimusEnablement " << *NvOptimusEnablement; - *NvOptimusEnablement = 0; - } - if (AmdPowerXpressRequestHighPerformance) { - // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance; - *AmdPowerXpressRequestHighPerformance = 0; - } -#endif -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_native_wayland) - wxControl::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize); - else -#endif - wxMediaCtrl::Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE); -#ifdef __LINUX__ - gstbambusrc_register(); -#ifdef __WXGTK__ - if (m_native_wayland && m_gtk_sink_error.empty()) - m_use_gtk_sink = CreateGtkSinkPlayer(); - if (m_native_wayland && !m_use_gtk_sink && m_gtk_sink_error.empty()) - m_gtk_sink_error = _L("Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation."); -#endif - if (!m_use_gtk_sink && m_imp) { - auto playbin = reinterpret_cast(m_imp)->m_playbin; - g_object_set(G_OBJECT(playbin), - "audio-sink", nullptr, - nullptr); - } else if (!m_use_gtk_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: wxMediaCtrl backend is unavailable"; - } - Bind(wxEVT_MEDIA_LOADED, [this](auto & e) { - m_loaded = true; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(0); - event.SetEventObject(this); - wxPostEvent(this, event); - }); -#endif -} - -wxMediaCtrl2::~wxMediaCtrl2() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - DestroyGtkSinkPlayer(); -#endif -} - -#if defined(__LINUX__) && defined(__WXGTK__) -bool wxMediaCtrl2::CreateGtkSinkPlayer() -{ - GstElement *playbin = gst_element_factory_make("playbin", "orca-wayland-gtk-playbin"); - if (!playbin) - return false; - - GError *error = nullptr; - GstElement *video_sink = gst_parse_bin_from_description( - "videoconvert ! videoscale ! video/x-raw,format=BGRx ! gtksink name=orca_wayland_gtksink sync=false", - TRUE, - &error); - if (!video_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: failed to create gtksink video bin" - << (error ? std::string(": ") + error->message : std::string()); - if (error) - g_error_free(error); - gst_object_unref(playbin); - return false; - } - - GstElement *gtk_sink = gst_bin_get_by_name(GST_BIN(video_sink), "orca_wayland_gtksink"); - if (!gtk_sink) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: failed to find gtksink in video bin"; - gst_object_unref(video_sink); - gst_object_unref(playbin); - return false; - } - - GtkWidget *gtk_widget = nullptr; - g_object_get(G_OBJECT(gtk_sink), "widget", >k_widget, nullptr); - if (!gtk_widget) { - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: gtksink did not expose a GtkWidget"; - gst_object_unref(gtk_sink); - gst_object_unref(video_sink); - gst_object_unref(playbin); - return false; - } - - gtk_widget_show(gtk_widget); - m_gtk_video_window = new wxNativeWindow(this, wxID_ANY, gtk_widget); - m_gtk_video_window->Show(); - g_object_unref(gtk_widget); - - g_object_set(G_OBJECT(playbin), - "video-sink", video_sink, - "audio-sink", nullptr, - nullptr); - gst_object_unref(video_sink); - - m_gtk_playbin = playbin; - m_gtk_sink = gtk_sink; - - GstBus *bus = gst_element_get_bus(playbin); - m_gtk_bus_watch_id = gst_bus_add_watch(bus, [](GstBus *, GstMessage *message, gpointer data) -> gboolean { - auto *self = static_cast(data); - if (!self || !self->m_gtk_playbin) - return G_SOURCE_REMOVE; - - switch (GST_MESSAGE_TYPE(message)) { - case GST_MESSAGE_ERROR: - { - GError *error = nullptr; - gchar *debug = nullptr; - gst_message_parse_error(message, &error, &debug); - BOOST_LOG_TRIVIAL(warning) << "wxMediaCtrl2: gtksink pipeline error" - << (error ? std::string(": ") + error->message : std::string()) - << (debug ? std::string(" debug: ") + debug : std::string()); - if (error) - g_error_free(error); - if (debug) - g_free(debug); - - self->m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(self->GetId()); - break; - } - case GST_MESSAGE_EOS: - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(self->GetId()); - break; - case GST_MESSAGE_STATE_CHANGED: - if (GST_MESSAGE_SRC(message) == GST_OBJECT(self->m_gtk_playbin)) { - GstState old_state; - GstState new_state; - GstState pending_state; - gst_message_parse_state_changed(message, &old_state, &new_state, &pending_state); - - if (new_state == GST_STATE_PLAYING) { - self->m_loaded = true; - self->m_gtk_state = wxMEDIASTATE_PLAYING; - self->PostGtkSinkStateEvent(); - } else if (new_state == GST_STATE_PAUSED && old_state < GST_STATE_PAUSED) { - // Treat only upward READY/NULL -> PAUSED as load completion. - // PLAYING -> PAUSED is a normal teardown step before NULL. - self->m_loaded = true; - self->m_gtk_state = wxMEDIASTATE_PAUSED; - self->PostGtkSinkStateEvent(); - } else if (new_state <= GST_STATE_READY && old_state >= GST_STATE_PAUSED) { - self->m_loaded = false; - self->m_gtk_state = wxMEDIASTATE_STOPPED; - self->PostGtkSinkStateEvent(); - } - } - break; - default: - break; - } - - return G_SOURCE_CONTINUE; - }, this); - gst_object_unref(bus); - - BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: using GTK native Wayland video sink"; - return true; -} - -void wxMediaCtrl2::DestroyGtkSinkPlayer() -{ - if (m_gtk_bus_watch_id) { - g_source_remove(m_gtk_bus_watch_id); - m_gtk_bus_watch_id = 0; - } - - if (m_gtk_playbin) { - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - } - - if (m_gtk_video_window) { - m_gtk_video_window->Destroy(); - m_gtk_video_window = nullptr; - } - - if (m_gtk_playbin) { - gst_object_unref(m_gtk_playbin); - m_gtk_playbin = nullptr; - } - - if (m_gtk_sink) { - gst_object_unref(m_gtk_sink); - m_gtk_sink = nullptr; - } - -} - -void wxMediaCtrl2::PostGtkSinkStateEvent(int id) -{ - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(id); - event.SetEventObject(this); - wxPostEvent(this, event); -} -#endif // defined(__LINUX__) && defined(__WXGTK__) - -#define CLSID_BAMBU_SOURCE L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" - -void wxMediaCtrl2::Load(wxURI url) -{ -#ifdef __WIN32__ - InvalidateBestSize(); - if (m_imp == nullptr) { - static bool notified = false; - if (!notified) CallAfter([] { - auto res = wxMessageBox(_L("Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?"), _L("Error"), wxOK | wxCANCEL); - if (res == wxOK) { - wxString url = IsWindows10OrGreater() - ? "ms-settings:optionalfeatures?activationSource=SMC-Article-14209" - : "https://support.microsoft.com/en-au/windows/get-windows-media-player-81718e0d-cfce-25b1-aee3-94596b658287"; - wxExecute("cmd /c start " + url, wxEXEC_HIDE_CONSOLE); - } - }); - m_error = 100; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - { - wxRegKey key11(wxRegKey::HKCU, L"SOFTWARE\\Classes\\CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); - wxRegKey key12(wxRegKey::HKCR, L"CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); - wxString path = key11.Exists() ? key11.QueryDefaultValue() - : key12.Exists() ? key12.QueryDefaultValue() : wxString{}; - wxRegKey key2(wxRegKey::HKCR, "bambu"); - wxString clsid; - if (key2.Exists()) - key2.QueryRawValue("Source Filter", clsid); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": clsid %1% path %2%") % clsid % path; - - std::string data_dir_str = Slic3r::data_dir(); - boost::filesystem::path data_dir_path(data_dir_str); - auto dll_path = data_dir_path / "plugins" / "BambuSource.dll"; - if (path.empty() || !wxFile::Exists(path) || clsid != CLSID_BAMBU_SOURCE) { - if (boost::filesystem::exists(dll_path)) { - CallAfter( - [dll_path] { - int res = wxMessageBox(_L("BambuSource has not correctly been registered for media playing! Press Yes to re-register it. You will be promoted twice"), _L("Error"), wxYES_NO); - if (res == wxYES) { - std::string regContent = R"(Windows Registry Editor Version 5.00 - [HKEY_CLASSES_ROOT\bambu] - "Source Filter"="{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" - )"; - - auto reg_path = (fs::temp_directory_path() / fs::unique_path()).replace_extension(".reg"); - std::ofstream temp_reg_file(reg_path.c_str()); - if (!temp_reg_file) { - return false; - } - temp_reg_file << regContent; - temp_reg_file.close(); - auto sei_params = L"/q /s " + reg_path.wstring(); - SHELLEXECUTEINFO sei{sizeof(sei), SEE_MASK_NOCLOSEPROCESS, NULL, L"open", - L"regedit", sei_params.c_str(),SW_HIDE,SW_HIDE}; - ::ShellExecuteEx(&sei); - - wstring quoted_dll_path = L"\"" + dll_path.wstring() + L"\""; - SHELLEXECUTEINFO info{sizeof(info), 0, NULL, L"runas", L"regsvr32", quoted_dll_path.c_str(), SW_HIDE }; - ::ShellExecuteEx(&info); - fs::remove(reg_path); - } - return true; - }); - } else { - CallAfter([] { - wxMessageBox(_L("Missing BambuSource component registered for media playing! Please re-install OrcaSlicer or seek community help."), _L("Error"), wxOK); - }); - } - m_error = clsid != CLSID_BAMBU_SOURCE ? 101 : path.empty() ? 102 : 103; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - if (path != dll_path) { - static bool notified = false; - if (!notified) CallAfter([dll_path] { - int res = wxMessageBox(_L("Using a BambuSource from a different install, video play may not work correctly! Press Yes to fix it."), _L("Warning"), wxYES_NO | wxICON_WARNING); - if (res == wxYES) { - auto path = dll_path.wstring(); - if (path.find(L' ') != std::wstring::npos) - path = L"\"" + path + L"\""; - SHELLEXECUTEINFO info{sizeof(info), 0, NULL, L"open", L"regsvr32", path.c_str(), SW_HIDE}; - ::ShellExecuteEx(&info); - } - }); - notified = true; - } - wxRegKey keyWmp(wxRegKey::HKCU, "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\."); - keyWmp.Create(); - long permissions = 0; - if (keyWmp.HasValue("Permissions")) - keyWmp.QueryValue("Permissions", &permissions); - if ((permissions & 32) == 0) { - permissions |= 32; - keyWmp.SetValue("Permissions", permissions); - } - } - url = wxURI(url.BuildURI().append("&hwnd=").append(boost::lexical_cast(GetHandle())).append("&tid=").append( - boost::lexical_cast(GetCurrentThreadId()))); -#endif -#ifdef __WXGTK3__ - GstElementFactory *factory; - int hasplugins = 1; - - factory = gst_element_factory_find("h264parse"); - if (!factory) { - hasplugins = 0; - } else { - gst_object_unref(factory); - } - - factory = gst_element_factory_find("openh264dec"); - if (!factory) { - factory = gst_element_factory_find("avdec_h264"); - } - if (!factory) { - factory = gst_element_factory_find("vaapih264dec"); - } - if (!factory) { - factory = gst_element_factory_find("vah264dec"); - } - if (!factory) { - factory = gst_element_factory_find("nvh264dec"); - } - if (!factory) { - factory = gst_element_factory_find("v4l2h264dec"); - } - if (!factory) { - hasplugins = 0; - } else { - gst_object_unref(factory); - } - - if (!hasplugins) { - CallAfter([] { - wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)"), _L("Error"), wxOK); - }); - m_error = 101; - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } - wxLog::EnableLogging(false); -#endif - m_error = 0; - m_loaded = false; -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - const std::string uri = std::string(url.BuildURI().ToUTF8().data()); - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - g_object_set(G_OBJECT(m_gtk_playbin), "uri", uri.c_str(), nullptr); - m_gtk_state = wxMEDIASTATE_STOPPED; - GstStateChangeReturn state = gst_element_set_state(m_gtk_playbin, GST_STATE_PAUSED); - if (state == GST_STATE_CHANGE_FAILURE) { - m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - PostGtkSinkStateEvent(GetId()); - } - return; - } - if (!m_imp) { - m_error = m_native_wayland && !m_gtk_sink_error.empty() ? 104 : 100; - m_loaded = false; - if (m_native_wayland && !m_gtk_sink_error.empty() && !m_gtk_sink_error_notified) { - m_gtk_sink_error_notified = true; - const wxString message = m_gtk_sink_error; - CallAfter([message] { - wxMessageBox(message, _L("Error"), wxOK); - }); - } - wxMediaEvent event(wxEVT_MEDIA_STATECHANGED); - event.SetId(GetId()); - event.SetEventObject(this); - wxPostEvent(this, event); - return; - } -#endif - wxMediaCtrl::Load(url); -} - -void wxMediaCtrl2::Play() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - GstStateChangeReturn state = gst_element_set_state(m_gtk_playbin, GST_STATE_PLAYING); - if (state == GST_STATE_CHANGE_FAILURE) { - m_error = gst_bambu_last_error ? gst_bambu_last_error : 2; - m_gtk_state = wxMEDIASTATE_STOPPED; - PostGtkSinkStateEvent(GetId()); - } - return; - } - if (!m_imp) { - m_error = m_native_wayland && !m_gtk_sink_error.empty() ? 104 : 100; - if (m_native_wayland && !m_gtk_sink_error.empty() && !m_gtk_sink_error_notified) { - m_gtk_sink_error_notified = true; - const wxString message = m_gtk_sink_error; - CallAfter([message] { - wxMessageBox(message, _L("Error"), wxOK); - }); - } - PostGtkSinkStateEvent(GetId()); - return; - } -#endif - wxMediaCtrl::Play(); -} - -void wxMediaCtrl2::Stop() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) { - gst_element_set_state(m_gtk_playbin, GST_STATE_NULL); - m_gtk_state = wxMEDIASTATE_STOPPED; - m_loaded = false; - PostGtkSinkStateEvent(0); - return; - } - if (!m_imp) - return; -#endif - wxMediaCtrl::Stop(); } - -void wxMediaCtrl2::SetIdleImage(wxString const &image) {} - -wxMediaState wxMediaCtrl2::GetState() -{ -#if defined(__LINUX__) && defined(__WXGTK__) - if (m_use_gtk_sink && m_gtk_playbin) - return m_gtk_state; - if (!m_imp) - return wxMEDIASTATE_STOPPED; -#endif - return wxMediaCtrl::GetState(); -} - -int wxMediaCtrl2::GetLastError() const -{ -#ifdef __LINUX__ -#ifdef __WXGTK__ - if (m_use_gtk_sink && m_error) - return m_error; -#endif - if (m_error) - return m_error; - return gst_bambu_last_error; -#else - return m_error; -#endif -} - -wxSize wxMediaCtrl2::GetVideoSize() const -{ -#ifdef __LINUX__ - // Gstreamer doesn't give us a VideoSize until we're playing, which - // confuses the MediaPlayCtrl into claiming that it is stuck - // "Loading...". Fake it out for now. - return m_loaded ? wxSize(1280, 720) : wxSize{}; -#else - wxSize size = m_imp ? m_imp->GetVideoSize() : wxSize(0, 0); - if (size.GetWidth() > 0) - const_cast(m_video_size) = size; - return size; -#endif -} - -wxSize wxMediaCtrl2::DoGetBestSize() const -{ - return {-1, -1}; -} - -void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) -{ - wxWindow::DoSetSize(x, y, width, height, sizeFlags); - if (sizeFlags & wxSIZE_USE_EXISTING) return; -#if defined(__LINUX__) && defined(__WXGTK__) - // Keep the native GStreamer video window filling the client area. - if (m_gtk_video_window) { - const wxSize client_size = GetClientSize(); - m_gtk_video_window->SetSize(0, 0, client_size.GetWidth(), client_size.GetHeight()); - } -#endif - wxMediaCtrl_OnSize(this, m_video_size, width, height); -} - -#ifdef __WIN32__ - -WXLRESULT wxMediaCtrl2::MSWWindowProc(WXUINT nMsg, - WXWPARAM wParam, - WXLPARAM lParam) -{ - // The stream source sends WM_USER+1000 with a synchronous SendMessage from its own threads, - // so this runs re-entrantly on the UI thread at whatever message-retrieval point the player - // happens to be in - often nested inside an Orca log statement. Never BOOST_LOG_TRIVIAL here: - // boost::log is not re-entrant on one thread, and doing so corrupted its per-thread record - // state, crashing later in unrelated places (the player, the log filter, a plug-in heap free). - // Post the string out (as the stat branch does) and log it on a clean stack instead. - if (nMsg == WM_USER + 1000) { - wxString msg((wchar_t const *) lParam); - if (wParam == 1) { - if (msg.EndsWith("]")) { - int n = msg.find_last_of('['); - if (n != wxString::npos) { - long val = 0; - if (msg.SubString(n + 1, msg.Length() - 2).ToLong(&val)) - m_error = (int) val; - } - } else if (msg.Contains("stat_log")) { - wxCommandEvent evt(EVT_MEDIA_CTRL_STAT); - evt.SetEventObject(this); - evt.SetString(msg.Mid(msg.Find(' ') + 1)); - wxPostEvent(this, evt); - } - } - return 0; - } - return wxMediaCtrl::MSWWindowProc(nMsg, wParam, lParam); -} - -#endif diff --git a/src/slic3r/GUI/wxMediaCtrl2.h b/src/slic3r/GUI/wxMediaCtrl2.h deleted file mode 100644 index a29bf6dba6..0000000000 --- a/src/slic3r/GUI/wxMediaCtrl2.h +++ /dev/null @@ -1,75 +0,0 @@ -// -// wxMediaCtrl2.h -// libslic3r_gui -// -// Created by cmguo on 2021/12/7. -// - -#ifndef wxMediaCtrl2_h -#define wxMediaCtrl2_h - -#include "wx/uri.h" -#include "wx/mediactrl.h" - -wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); - -void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height); - -#if defined(__LINUX__) && defined(__WXGTK__) -typedef struct _GstElement GstElement; -#endif - -class wxMediaCtrl2 : public wxMediaCtrl -{ -public: - wxMediaCtrl2(wxWindow *parent); - ~wxMediaCtrl2(); - - void Load(wxURI url); - - void Play(); - - void Stop(); - - void SetIdleImage(wxString const & image); - - wxMediaState GetState(); - - int GetLastError() const; - - wxSize GetVideoSize() const; - -protected: - wxSize DoGetBestSize() const override; - - void DoSetSize(int x, int y, int width, int height, int sizeFlags) override; - -#ifdef __WIN32__ - WXLRESULT MSWWindowProc(WXUINT nMsg, - WXWPARAM wParam, - WXLPARAM lParam) override; -#endif - -private: -#if defined(__LINUX__) && defined(__WXGTK__) - bool CreateGtkSinkPlayer(); - void DestroyGtkSinkPlayer(); - void PostGtkSinkStateEvent(int id = 0); - - bool m_native_wayland = false; - bool m_use_gtk_sink = false; - wxString m_gtk_sink_error; - bool m_gtk_sink_error_notified = false; - GstElement *m_gtk_playbin = nullptr; - GstElement *m_gtk_sink = nullptr; - unsigned int m_gtk_bus_watch_id = 0; - wxWindow *m_gtk_video_window = nullptr; - wxMediaState m_gtk_state = wxMEDIASTATE_STOPPED; -#endif - wxString m_idle_image; - int m_error = 0; - bool m_loaded = false; - wxSize m_video_size{16, 9}; -}; - -#endif /* wxMediaCtrl2_h */