diff --git a/src/include/display-handles.h b/src/include/display-handles.h index 5e104f885..d2ce897ee 100644 --- a/src/include/display-handles.h +++ b/src/include/display-handles.h @@ -14,6 +14,9 @@ /** @file display-handles.h ** Opaque handles and similar typedefs used to communicate via the ** lumiera::Display and lumiera::DummyPlayer facade interfaces. + ** + ** @deprecated this is part of prototyping code; as of 5/2025 it is clear + ** that we will not use any of these interface schemes (yet something similar) ** ** @see stage::DisplayService ** @@ -43,4 +46,18 @@ typedef struct lumiera_playprocess_struct lumiera_playprocess; typedef lumiera_playprocess* LumieraPlayProcess; -#endif +#ifdef __cplusplus +namespace lumiera { + + /** Supported Displayer formats */ + enum DisplayerInput { + DISPLAY_NONE, + DISPLAY_YUV, + DISPLAY_RGB, + DISPLAY_BGR, + DISPLAY_BGR0, + DISPLAY_RGB16 + }; +} // namespace lumiera +#endif /*__cplusplus*/ +#endif /*LUMIERA_DISPLAY_HANDLES_H*/ diff --git a/src/stage/ctrl/demo-controller.cpp b/src/stage/ctrl/demo-controller.cpp index 841f45020..987ce877a 100644 --- a/src/stage/ctrl/demo-controller.cpp +++ b/src/stage/ctrl/demo-controller.cpp @@ -37,17 +37,28 @@ namespace ctrl { using std::make_unique; using steam::node::TickService; using steam::node::DummyImageGenerator; + using lumiera::DisplayerInput; - DemoController::DemoController(FrameSink outputSink) + DemoController::DemoController() : imageGen_{make_unique(FPS)} , tick_{} - , output_{std::move (outputSink)} + , output_{} , playing_{false} { } DemoController::~DemoController() { stop(); } + /** Signal slot to be called after the output window was created + * and the actually usable video display technology has been determined. + * @param displayFormat format for the frames expected in the passed image buffer. + */ + void + DemoController::activate (lumiera::DisplayerInput displayFormat) + { + REQUIRE (imageGen_); + imageGen_->configure (displayFormat); + } void DemoController::processFrame() diff --git a/src/stage/ctrl/demo-controller.hpp b/src/stage/ctrl/demo-controller.hpp index 1b8a993ab..8d049432a 100644 --- a/src/stage/ctrl/demo-controller.hpp +++ b/src/stage/ctrl/demo-controller.hpp @@ -32,6 +32,7 @@ #define DEMO_CONTROLLER_H #include "stage/gtk-base.hpp" +#include "include/display-handles.h" #include "lib/nocopy.hpp" #include @@ -47,21 +48,19 @@ namespace stage { namespace ctrl { using std::unique_ptr; - using FrameSink = std::function; /** @deprecated we need a durable design for the playback process */ class DemoController : util::NonCopyable + , public sigc::trackable { unique_ptr imageGen_; unique_ptr tick_; - FrameSink output_; - bool playing_; public: ~DemoController(); - DemoController(FrameSink); + DemoController(); bool isPlaying() const { return playing_; } @@ -69,7 +68,10 @@ namespace ctrl { void pause(); void stop(); + void activate (lumiera::DisplayerInput); + sigc::signal output_; private: + bool playing_; void processFrame(); }; diff --git a/src/stage/output/displayer.cpp b/src/stage/output/displayer.cpp index 7ef3107ec..a80fbcc2a 100644 --- a/src/stage/output/displayer.cpp +++ b/src/stage/output/displayer.cpp @@ -38,7 +38,7 @@ namespace output { DisplayerInput Displayer::format() { - return DISPLAY_NONE; + return lumiera::DISPLAY_NONE; } void diff --git a/src/stage/output/displayer.hpp b/src/stage/output/displayer.hpp index 52436073c..3392aa8e5 100644 --- a/src/stage/output/displayer.hpp +++ b/src/stage/output/displayer.hpp @@ -28,19 +28,12 @@ #include "lib/nocopy.hpp" +#include "include/display-handles.h" namespace stage { namespace output { - /** Supported Displayer formats */ - enum DisplayerInput { - DISPLAY_NONE, - DISPLAY_YUV, - DISPLAY_RGB, - DISPLAY_BGR, - DISPLAY_BGR0, - DISPLAY_RGB16 - }; + using lumiera::DisplayerInput; /** diff --git a/src/stage/output/pixbuf-displayer.cpp b/src/stage/output/pixbuf-displayer.cpp index af0692966..fb366d1d5 100644 --- a/src/stage/output/pixbuf-displayer.cpp +++ b/src/stage/output/pixbuf-displayer.cpp @@ -23,13 +23,6 @@ #include "stage/gtk-base.hpp" #include "stage/output/pixbuf-displayer.hpp" -#include "lib/format-cout.hpp" - -#if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display -#include -#endif ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display -#include - namespace stage { @@ -44,7 +37,7 @@ namespace output { REQUIRE (height > 0); auto iconSet = Gtk::IconSet::lookup_default (Gtk::StockID("panel_play")); drawingArea_.set(iconSet, Gtk::IconSize(Gtk::ICON_SIZE_DIALOG)); - cout << "USING PixbufDisplayer" <gobj(); - REQUIRE (window != NULL); - - #if false ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display - GdkGC *gc = gdk_gc_new( window ); - REQUIRE(gc != NULL); - - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8, - preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL ); - REQUIRE(pixbuf != NULL); - - GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, destWidth, destHeight, GDK_INTERP_NEAREST ); - REQUIRE(scaled_image != NULL); - - gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, orgX, orgY, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 ); - - g_object_unref( scaled_image ); - g_object_unref( pixbuf ); - g_object_unref( gc ); - #endif ///////////////////////////////////////////////////////////////////////////////////////////////////TICKET #950 : new solution for video display auto* imageData = static_cast (image); - auto rawBuf = Gdk::Pixbuf::create_from_data (imageData + auto imgBuf = Gdk::Pixbuf::create_from_data (imageData ,Gdk::COLORSPACE_RGB ,false // has_alpha ,8 // bits_per_sample ,videoWidth ,videoHeight - ,0 // rowstride (can be used to round up to even powers of two per row) + ,3 * videoWidth // rowstride (offset between consecutive rows) ); - ASSERT (rawBuf); - auto scaledBuf = rawBuf->scale_simple (destWidth, destHeight, Gdk::INTERP_NEAREST); - drawingArea_.set (scaledBuf); + ASSERT (imgBuf); + if (uint(destWidth) != videoWidth + or uint(destHeight) != videoHeight) + imgBuf = imgBuf->scale_simple (destWidth, destHeight, Gdk::INTERP_NEAREST); + drawingArea_.set (imgBuf); drawingArea_.queue_draw(); - cout << "bong.."<format()); } @@ -70,11 +71,11 @@ namespace widget { { REQUIRE (videoWidth > 0); REQUIRE (videoHeight > 0); - + /* ///////////////////////////////TICKET #1403 : temporarily disabled XV for experimentation with Pixbuf (but XV works and is usable) displayer_ = make_unique (*this, videoWidth, videoHeight); if (displayer_->usable()) return; - + */ displayer_ = make_unique (*this, videoWidth, videoHeight); if (displayer_->usable()) return; diff --git a/src/stage/widget/video-display-widget.hpp b/src/stage/widget/video-display-widget.hpp index daf8c8155..4a625af0e 100644 --- a/src/stage/widget/video-display-widget.hpp +++ b/src/stage/widget/video-display-widget.hpp @@ -32,6 +32,7 @@ namespace stage { namespace widget { using stage::output::Displayer; + using lumiera::DisplayerInput; /** @@ -48,8 +49,11 @@ namespace widget { public: VideoDisplayWidget(); + /** signal slot to display the next frame */ void pushFrame (void* const); + /** signal to configure the image generation format */ + sigc::signal signal_activate; private: virtual void on_realize() override; diff --git a/src/stage/workspace/panel-manager.cpp b/src/stage/workspace/panel-manager.cpp index a60a80c8a..605dc9de8 100644 --- a/src/stage/workspace/panel-manager.cpp +++ b/src/stage/workspace/panel-manager.cpp @@ -74,7 +74,7 @@ namespace workspace { ///////////////////////////////////////////////////////TICKET #172 : observed as a reason for crashes when closing the GUI. It was invoked after end of main, when the GUI as already gone. #if false ///////////////////////////////////////////////////TICKET #937 : disabled for GTK-3 transition. TODO investigate why this logic existed... - ///////////////////////////////////////////////////////TICKET #1027 + ///////////////////////////////////////////////////////TICKET #1027: but now the destructors of components attached to docking panel are not invoked any more !! for(int i = 0; i < 4; i++) if(dockPlaceholders_[i]) g_object_unref(dockPlaceholders_[i]); diff --git a/src/steam/engine/worker/dummy-image-generator.cpp b/src/steam/engine/worker/dummy-image-generator.cpp index 237f50eca..1085194ec 100644 --- a/src/steam/engine/worker/dummy-image-generator.cpp +++ b/src/steam/engine/worker/dummy-image-generator.cpp @@ -80,10 +80,21 @@ namespace node { DummyImageGenerator::DummyImageGenerator(uint fps) : fps_{fps} + , useRGB_{false} , beat_{false} , frame_{0} { } + void + DummyImageGenerator::configure (lumiera::DisplayerInput displayFormat) + { + INFO (steam, "ImageGen: use format %d", displayFormat); + REQUIRE ( displayFormat == lumiera::DISPLAY_NONE + or displayFormat == lumiera::DISPLAY_YUV + or displayFormat == lumiera::DISPLAY_RGB); + + useRGB_ = (displayFormat == lumiera::DISPLAY_RGB); + } void DummyImageGenerator::generateFrame (DummyFrame buffer) @@ -153,9 +164,11 @@ namespace node { DummyFrame outBuff = current(); // next output buffer to return - generateFrame (workBuf_.data()); + DummyFrame workspace = useRGB_? outBuff : workBuf_.data(); + generateFrame (workspace); + if (not useRGB_) + rgb_buffer_to_yuy2(workBuf_.data(), outBuff, W*H); - rgb_buffer_to_yuy2(workBuf_.data(), outBuff, W*H); return outBuff; } diff --git a/src/steam/engine/worker/dummy-image-generator.hpp b/src/steam/engine/worker/dummy-image-generator.hpp index e54d000cf..ee542d521 100644 --- a/src/steam/engine/worker/dummy-image-generator.hpp +++ b/src/steam/engine/worker/dummy-image-generator.hpp @@ -33,6 +33,8 @@ #include "lib/error.hpp" #include "include/display-facade.h" +#include "include/display-handles.h" + #include @@ -44,12 +46,15 @@ namespace node { class DummyImageGenerator { uint fps_; + bool useRGB_; public: static const uint W = 320; static const uint H = 240; DummyImageGenerator(uint fps); + void configure (lumiera::DisplayerInput); + /** generate the next frame and occupy the alternate buffer. * @return the buffer containing the new frame */ diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 845136d66..fc2af33a2 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -129648,14 +129648,14 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - - - + + + - + @@ -129682,7 +129682,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129703,7 +129703,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129716,7 +129716,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129758,25 +129758,29 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - - + + + + + - - + + - - + + + + + @@ -129808,7 +129812,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129923,7 +129927,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -129988,7 +129992,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -130017,11 +130021,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - - - +

Erfolg-1 : es wird irgendwas angezeigt @@ -130038,56 +130040,59 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + - + + - - + + - + - - - - - - + + + + + + - - - + + + - + - - - - - + + + + + - + - - - - - + + + + + - - - +

beziehe mich hier per Gedächtnis auf Sachverhalte, die ich irgenwann irgendwo mal gelesen habe; demnach kann XV mit irgend einer Art von »Compositor« zusammenarbeiten, notfalls aber seine sichtbare (clipping)-Region auch per Colour-Key herausfinden; dabei geht es um die Frage, welcher Teil des Videobildes tatsächlich auf dem Desktop zu sehen ist, denn das Fenster könnte partiell verdeckt sein @@ -130096,45 +130101,71 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - + - - - - + + + + - + - + - - - + + + - + + - - - + + + + + + +

+ ...und gehört in einen dedizierten OutputManager +

+ + +
+
+ + + + +

+ er rechnet ja ohnehin zunächst in RGB, und macht dann eine YUV-Konvertierung +

+ + +
+ +
+
+ + + + - - - +

Tip: suche nach "image data" @@ -130160,7 +130191,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -130179,7 +130210,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -130199,9 +130230,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - +

sieht zwar nach nitpicking aus, aber da wir dann explizit per structured-Binding auf die Komponenten zugreifen, könnte der Code etwas klarer werden @@ -130220,9 +130249,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - +

...sonst ist es nicht möglich, das als virtuellen Zugriff für Input und Output zu verwenden @@ -130239,6 +130266,82 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...was jetzt einfach an dem Test-Setup liegt, in dem die Komponenten nochmal gewrapped sind +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -130253,9 +130356,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - +

...denn sonst endet man doch wieder mit z.B. einem Debian-Paket, das build-depends on the world of media processing @@ -130276,9 +130377,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - +

sie könnte zwar im System installiert und vorhanden sein, aber nicht richtig konfiguriert, vielleicht überhaupt nie nutzbar sein, oder aber derzeit grade nicht nutzbar (weil eine externe Verbindung oder Ressource fehlt) @@ -142480,7 +142579,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - +