diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index da0b62ddf..8222a3956 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -78,7 +78,9 @@ using namespace nlohmann; #include "slic3r/GUI/Camera.hpp" #include - +#ifdef __WXGTK__ +#include +#endif #ifdef SLIC3R_GUI #include "slic3r/GUI/GUI_Init.hpp" @@ -332,6 +334,10 @@ int CLI::run(int argc, char **argv) // startup if gtk3 is used. This env var has to be set explicitly to // instruct the window manager to fall back to X server mode. ::setenv("GDK_BACKEND", "x11", /* replace */ true); + + // Also on Linux, we need to tell Xlib that we will be using threads, + // lest we crash when we fire up GStreamer. + XInitThreads(); #endif // Switch boost::filesystem to utf8. diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 49fe4e04b..8ea21fb58 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -437,6 +437,12 @@ else () ) endif () +if (UNIX AND NOT APPLE) + list(APPEND SLIC3R_GUI_SOURCES + GUI/Printer/gstbambusrc.c + ) +endif () + add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) target_include_directories(libslic3r_gui PRIVATE Utils) @@ -491,4 +497,10 @@ if (UNIX AND NOT APPLE) find_package(GTK${SLIC3R_GTK} REQUIRED) target_include_directories(libslic3r_gui PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS}) target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES}) + + # We add GStreamer for bambu:/// support. + pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0) + pkg_check_modules(GST_BASE REQUIRED gstreamer-base-1.0) + target_link_libraries(libslic3r_gui ${GSTREAMER_LIBRARIES} ${GST_BASE_LIBRARIES}) + target_include_directories(libslic3r_gui PRIVATE ${GSTREAMER_INCLUDE_DIRS} ${GST_BASE_INCLUDE_DIRS}) endif () diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 89e9d4b27..2aba533e0 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -541,7 +541,11 @@ bool MediaPlayCtrl::get_stream_url(std::string *url) void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) { +#ifdef __WXMAC__ wxWindow::DoSetSize(x, y, width, height, sizeFlags); +#else + wxMediaCtrl::DoSetSize(x, y, width, height, sizeFlags); +#endif if (sizeFlags & wxSIZE_USE_EXISTING) return; wxSize size = GetVideoSize(); if (size.GetWidth() <= 0) diff --git a/src/slic3r/GUI/Notebook.cpp b/src/slic3r/GUI/Notebook.cpp index bc80e8862..a6bec54be 100644 --- a/src/slic3r/GUI/Notebook.cpp +++ b/src/slic3r/GUI/Notebook.cpp @@ -258,5 +258,14 @@ void Notebook::Init() m_showEffect = m_hideEffect = wxSHOW_EFFECT_NONE; m_showTimeout = m_hideTimeout = 0; + + /* On Linux, Gstreamer wxMediaCtrl does not seem to get along well with + * 32-bit X11 visuals (the overlay does not work). Is this a wxWindows + * bug? Is this a Gstreamer bug? No idea, but it is our problem ... + * and anyway, this transparency thing just isn't all that interesting, + * so we just don't do it on Linux. + */ +#ifndef __WXGTK__ SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); +#endif } diff --git a/src/slic3r/GUI/Printer/BambuTunnel.h b/src/slic3r/GUI/Printer/BambuTunnel.h index 11504a70c..405a44843 100644 --- a/src/slic3r/GUI/Printer/BambuTunnel.h +++ b/src/slic3r/GUI/Printer/BambuTunnel.h @@ -21,6 +21,15 @@ extern "C" { #endif // __cplusplus +#ifndef __cplusplus +#include + +/* We need these workarounds since we're compiling C source, not C++. */ +typedef enum Bambu_StreamType Bambu_StreamType; +typedef struct Bambu_StreamInfo Bambu_StreamInfo; +typedef struct Bambu_Sample Bambu_Sample; +#endif + #ifdef _WIN32 typedef wchar_t tchar; #else diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp index 56d62aa76..093459975 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp @@ -921,3 +921,7 @@ StaticBambuLib &StaticBambuLib::get() lib.Bambu_Create = Fake_Bambu_Create; return lib; } + +extern "C" struct BambuLib *bambulib_get() { + return &StaticBambuLib::get(); +} diff --git a/src/slic3r/GUI/Printer/gstbambusrc.c b/src/slic3r/GUI/Printer/gstbambusrc.c new file mode 100644 index 000000000..07341e4ce --- /dev/null +++ b/src/slic3r/GUI/Printer/gstbambusrc.c @@ -0,0 +1,554 @@ +/* bambusrc for gstreamer + * integration with proprietary Bambu Lab blob for getting raw h.264 video + * + * Copyright (C) 2023 Joshua Wise + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gstbambusrc.h" + +#include +#include +#ifndef EXTERNAL_GST_PLUGIN +#define BAMBU_DYNAMIC +#endif +#include "BambuTunnel.h" + +#ifdef BAMBU_DYNAMIC +// From PrinterFileSystem. +#ifdef __cplusplus +extern "C" +#else +extern +#endif +struct BambuLib *bambulib_get(); +static struct BambuLib *_lib = NULL; +#define BAMBULIB(x) (_lib->x) + +#else +#define BAMBULIB(x) (x) +#endif + +GST_DEBUG_CATEGORY_STATIC (gst_bambusrc_debug); +#define GST_CAT_DEFAULT gst_bambusrc_debug + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS("video/x-h264,framerate=0/1,parsed=(boolean)false,stream-format=(string)byte-stream")); + +enum +{ + PROP_0, + PROP_LOCATION, +}; + +static void gst_bambusrc_uri_handler_init (gpointer g_iface, + gpointer iface_data); +static void gst_bambusrc_finalize (GObject * gobject); +static void gst_bambusrc_dispose (GObject * gobject); + +static void gst_bambusrc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_bambusrc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstStateChangeReturn gst_bambusrc_change_state (GstElement * + element, GstStateChange transition); +static GstFlowReturn gst_bambusrc_create (GstPushSrc * psrc, + GstBuffer ** outbuf); +static gboolean gst_bambusrc_start (GstBaseSrc * bsrc); +static gboolean gst_bambusrc_stop (GstBaseSrc * bsrc); +static gboolean gst_bambusrc_is_seekable (GstBaseSrc * bsrc); +static gboolean gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query); +static gboolean gst_bambusrc_unlock (GstBaseSrc * bsrc); +static gboolean gst_bambusrc_unlock_stop (GstBaseSrc * bsrc); +static gboolean gst_bambusrc_set_location (GstBambuSrc * src, + const gchar * uri, GError ** error); + +#define gst_bambusrc_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstBambuSrc, gst_bambusrc, GST_TYPE_PUSH_SRC, + G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, + gst_bambusrc_uri_handler_init)); +GST_ELEMENT_REGISTER_DEFINE (bambusrc, "bambusrc", + GST_RANK_PRIMARY, GST_TYPE_BAMBUSRC); + +static void +gst_bambusrc_class_init (GstBambuSrcClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSrcClass *gstbasesrc_class; + GstPushSrcClass *gstpushsrc_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasesrc_class = (GstBaseSrcClass *) klass; + gstpushsrc_class = (GstPushSrcClass *) klass; + + gobject_class->set_property = gst_bambusrc_set_property; + gobject_class->get_property = gst_bambusrc_get_property; + gobject_class->finalize = gst_bambusrc_finalize; + gobject_class->dispose = gst_bambusrc_dispose; + + g_object_class_install_property (gobject_class, + PROP_LOCATION, + g_param_spec_string ("location", "Location", + "URI to pass to Bambu Lab blobs", "", + (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); + + gst_element_class_set_static_metadata (gstelement_class, "Bambu Lab source", + "Source/Network", + "Receive data as a client over the network using the proprietary Bambu Lab blobs", + "Joshua Wise "); + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_bambusrc_change_state); + + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_bambusrc_start); + gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_bambusrc_stop); + gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_bambusrc_unlock); + gstbasesrc_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_bambusrc_unlock_stop); + gstbasesrc_class->is_seekable = + GST_DEBUG_FUNCPTR (gst_bambusrc_is_seekable); + gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_bambusrc_query); + + gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_bambusrc_create); + + GST_DEBUG_CATEGORY_INIT (gst_bambusrc_debug, "bambusrc", 0, + "Bambu Lab src"); +} + +static void +gst_bambusrc_reset (GstBambuSrc * src) +{ + gst_caps_replace (&src->src_caps, NULL); + if (src->tnl) { + BAMBULIB(Bambu_Close)(src->tnl); + BAMBULIB(Bambu_Destroy)(src->tnl); + src->tnl = NULL; + } +} + +static void +gst_bambusrc_init (GstBambuSrc * src) +{ + src->location = NULL; + src->tnl = NULL; + + gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE); + gst_base_src_set_live(GST_BASE_SRC(src), TRUE); + + gst_bambusrc_reset (src); +} + +static void +gst_bambusrc_dispose (GObject * gobject) +{ + GstBambuSrc *src = GST_BAMBUSRC (gobject); + + GST_DEBUG_OBJECT (src, "dispose"); + + G_OBJECT_CLASS (parent_class)->dispose (gobject); +} + +static void +gst_bambusrc_finalize (GObject * gobject) +{ + GstBambuSrc *src = GST_BAMBUSRC (gobject); + + GST_DEBUG_OBJECT (src, "finalize"); + + g_free (src->location); + if (src->tnl) { + BAMBULIB(Bambu_Close)(src->tnl); + BAMBULIB(Bambu_Destroy)(src->tnl); + } + + G_OBJECT_CLASS (parent_class)->finalize (gobject); +} + +static void +gst_bambusrc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstBambuSrc *src = GST_BAMBUSRC (object); + + switch (prop_id) { + case PROP_LOCATION: + { + const gchar *location; + + location = g_value_get_string (value); + + if (location == NULL) { + GST_WARNING ("location property cannot be NULL"); + goto done; + } + if (!gst_bambusrc_set_location (src, location, NULL)) { + GST_WARNING ("badly formatted location"); + goto done; + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +done: + return; +} + +static void +gst_bambusrc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstBambuSrc *src = GST_BAMBUSRC (object); + + switch (prop_id) { + case PROP_LOCATION: + g_value_set_string (value, src->location); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstFlowReturn +gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf) +{ + GstBambuSrc *src; + + src = GST_BAMBUSRC (psrc); + + (void) src; + GST_DEBUG_OBJECT (src, "create()"); + + int rv; + struct Bambu_Sample sample; + + if (!src->tnl) { + return GST_FLOW_ERROR; + } + + while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) { + GST_DEBUG_OBJECT(src, "create would block"); + usleep(33333); /* 30Hz */ + } + + if (rv == Bambu_stream_end) { + return GST_FLOW_EOS; + } + + if (rv != Bambu_success) { + return GST_FLOW_ERROR; + } + + *outbuf = gst_buffer_new_memdup(sample.buffer, sample.size); + /* The NAL data already contains a timestamp (I think?), but we seem to + * need to feed this in too -- otherwise the GStreamer pipeline gets upset + * and starts triggering QoS events. + */ + if (!src->sttime) { + src->sttime = sample.decode_time * 100ULL; + } + GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime; + GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE; + GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE; + + return GST_FLOW_OK; +} + +static void _log(void *ctx, int lvl, const char *msg) { + GstBambuSrc *src = (GstBambuSrc *) ctx; + GST_DEBUG_OBJECT(src, "bambu: %s", msg); + BAMBULIB(Bambu_FreeLogMsg)(msg); +} + +static gboolean +gst_bambusrc_start (GstBaseSrc * bsrc) +{ + GstBambuSrc *src = GST_BAMBUSRC (bsrc); + + GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location); + + if (src->tnl) { + BAMBULIB(Bambu_Close)(src->tnl); + BAMBULIB(Bambu_Destroy)(src->tnl); + src->tnl = NULL; + } + +#ifdef BAMBU_DYNAMIC + if (!_lib) { + _lib = bambulib_get(); + if (!_lib->Bambu_Open) { + return FALSE; + } + } +#endif + if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) { + return FALSE; + } + + BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src); + if (BAMBULIB(Bambu_Open)(src->tnl) != Bambu_success) { + BAMBULIB(Bambu_Destroy)(src->tnl); + src->tnl = NULL; + return FALSE; + } + + int rv; + while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) { + usleep(100000); + } + if (rv != Bambu_success) { + BAMBULIB(Bambu_Close)(src->tnl); + BAMBULIB(Bambu_Destroy)(src->tnl); + src->tnl = NULL; + return FALSE; + } + + src->sttime = 0; + return TRUE; +} + +static gboolean +gst_bambusrc_stop (GstBaseSrc * bsrc) +{ + GstBambuSrc *src; + + src = GST_BAMBUSRC (bsrc); + GST_DEBUG_OBJECT (src, "stop()"); + if (src->tnl) { + BAMBULIB(Bambu_Close)(src->tnl); + BAMBULIB(Bambu_Destroy)(src->tnl); + src->tnl = NULL; + } + + return TRUE; +} + +static GstStateChangeReturn +gst_bambusrc_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + GstBambuSrc *src; + + src = GST_BAMBUSRC (element); + + (void) src; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + //gst_bambusrc_session_close (src); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + return ret; +} + +/* Interrupt a blocking request. */ +static gboolean +gst_bambusrc_unlock (GstBaseSrc * bsrc) +{ + GstBambuSrc *src; + + src = GST_BAMBUSRC (bsrc); + GST_DEBUG_OBJECT (src, "unlock()"); + + return TRUE; +} + +/* Interrupt interrupt. */ +static gboolean +gst_bambusrc_unlock_stop (GstBaseSrc * bsrc) +{ + GstBambuSrc *src; + + src = GST_BAMBUSRC (bsrc); + GST_DEBUG_OBJECT (src, "unlock_stop()"); + + return TRUE; +} + +static gboolean +gst_bambusrc_is_seekable (GstBaseSrc * bsrc) +{ + GstBambuSrc *src = GST_BAMBUSRC (bsrc); + + (void) src; + + return FALSE; +} + +static gboolean +gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query) +{ + GstBambuSrc *src = GST_BAMBUSRC (bsrc); + gboolean ret; + GstSchedulingFlags flags; + gint minsize, maxsize, align; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_URI: + gst_query_set_uri (query, src->location); + ret = TRUE; + break; + default: + ret = FALSE; + break; + } + + if (!ret) + ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_SCHEDULING: + gst_query_parse_scheduling (query, &flags, &minsize, &maxsize, &align); + flags = (GstSchedulingFlags)((int)flags | (int)GST_SCHEDULING_FLAG_SEQUENTIAL); + gst_query_set_scheduling (query, flags, minsize, maxsize, align); + break; + default: + break; + } + + return ret; +} + +static gboolean +gst_bambusrc_set_location (GstBambuSrc * src, const gchar * uri, + GError ** error) +{ + if (src->location) { + g_free (src->location); + src->location = NULL; + } + + if (uri == NULL) + return FALSE; + + src->location = g_strdup (uri); + + return TRUE; +} + +static GstURIType +gst_bambusrc_uri_get_type (GType type) +{ + return GST_URI_SRC; +} + +static const gchar *const * +gst_bambusrc_uri_get_protocols (GType type) +{ + static const gchar *protocols[] = { "bambu", NULL }; + + return protocols; +} + +static gchar * +gst_bambusrc_uri_get_uri (GstURIHandler * handler) +{ + GstBambuSrc *src = GST_BAMBUSRC (handler); + + /* FIXME: make thread-safe */ + return g_strdup (src->location); +} + +static gboolean +gst_bambusrc_uri_set_uri (GstURIHandler * handler, const gchar * uri, + GError ** error) +{ + GstBambuSrc *src = GST_BAMBUSRC (handler); + + return gst_bambusrc_set_location (src, uri, error); +} + +static void +gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_bambusrc_uri_get_type; + iface->get_protocols = gst_bambusrc_uri_get_protocols; + iface->get_uri = gst_bambusrc_uri_get_uri; + iface->set_uri = gst_bambusrc_uri_set_uri; +} + +static gboolean gstbambusrc_init(GstPlugin *plugin) +{ + return GST_ELEMENT_REGISTER (bambusrc, plugin); +} + +#ifndef EXTERNAL_GST_PLUGIN + +// for use inside of Bambu Slicer +void gstbambusrc_register() +{ + static int did_register = 0; + if (did_register) + return; + did_register = 1; + + gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio"); +} + +#else + +#ifndef PACKAGE +#define PACKAGE "bambusrc" +#endif + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, bambusrc, "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "https://github.com/bambulab/BambuStudio") + +#endif diff --git a/src/slic3r/GUI/Printer/gstbambusrc.h b/src/slic3r/GUI/Printer/gstbambusrc.h new file mode 100644 index 000000000..234842403 --- /dev/null +++ b/src/slic3r/GUI/Printer/gstbambusrc.h @@ -0,0 +1,73 @@ +/* bambusrc for gstreamer + * integration with proprietary Bambu Lab blob for getting raw h.264 video + * + * Copyright (C) 2023 Joshua Wise + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_BAMBUSRC_H__ +#define __GST_BAMBUSRC_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_BAMBUSRC (gst_bambusrc_get_type()) +G_DECLARE_FINAL_TYPE (GstBambuSrc, gst_bambusrc, + GST, BAMBUSRC, GstPushSrc) + +typedef void *Bambu_Tunnel; + +struct _GstBambuSrc +{ + GstPushSrc element; + GstCaps *src_caps; + gchar *location; + Bambu_Tunnel tnl; + GstClockTime sttime; +}; + +extern void gstbambusrc_register(); + +G_END_DECLS + +#endif /* __GST_BAMBUSRC_H__ */ diff --git a/src/slic3r/GUI/wxMediaCtrl2.cpp b/src/slic3r/GUI/wxMediaCtrl2.cpp index 0f8931fad..dde69727f 100644 --- a/src/slic3r/GUI/wxMediaCtrl2.cpp +++ b/src/slic3r/GUI/wxMediaCtrl2.cpp @@ -7,6 +7,10 @@ #include #endif +#ifdef __LINUX__ +#include "Printer/gstbambusrc.h" +#endif + wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent) { #ifdef __WIN32__ @@ -24,6 +28,10 @@ wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent) } #endif wxMediaCtrl::Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE); +#ifdef __LINUX__ + /* Register only after we have created the wxMediaCtrl, since only then are we guaranteed to have fired up Gstreamer's plugin registry. */ + gstbambusrc_register(); +#endif } #define CLSID_BAMBU_SOURCE L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" @@ -105,7 +113,14 @@ void wxMediaCtrl2::Stop() { wxMediaCtrl::Stop(); } 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 wxSize(1280, 720); +#else return m_imp ? m_imp->GetVideoSize() : wxSize(0, 0); +#endif } wxSize wxMediaCtrl2::DoGetBestSize() const diff --git a/src/slic3r/pchheader.hpp b/src/slic3r/pchheader.hpp index 816733f45..141383918 100644 --- a/src/slic3r/pchheader.hpp +++ b/src/slic3r/pchheader.hpp @@ -15,6 +15,8 @@ #include #include +#ifdef __cplusplus + #include #include #include @@ -194,3 +196,5 @@ #ifdef _WIN32 #include "GUI/format.hpp" #endif // _WIN32 + +#endif // __cplusplus