XV-Display: investigate and fix some problems with this XV code

Generally speaking, this experiment shows that we need some additional know-how
regarding the XVideo standard. And we should re-think the means of integration.

From some further debugging end experimenting with this code,
the following conlusions can be drawn:

- the code retrieves the GDK-Window, to which the widget was mapped
- it uses this to access an underlying X-Window
- seemingly the docking panel uses a separate X-Window, which also
  hosts the header area of the panel
- this whole underlying X-Window is treated with some compositing method,
  presumably (just guessing from the code) we use keying with a
  marker-colour. This explains why the whole area of the panel
  is no longer updated regularly
- furthermore, we need to take into account that the actual display widget
  area uses some part of this window, which can be found out from
  the VideoWidget's ''Allocation''
- when correcting the origin of the video display by using this
  allocation's origin, at least the display of the video is precisely
  at the right location and size

Furthermore, the code takes quite some shortcut and basically
looks for one specific display format, and uses the corresponding
configuration for the "port" it got.

This Format has the Abbreviation "YUY2" (packed)
This commit is contained in:
Fischlurch 2025-05-09 04:28:17 +02:00
parent 5d3710fca8
commit 42ce53aa09
3 changed files with 75 additions and 17 deletions

View file

@ -23,27 +23,32 @@
#include "stage/gtk-base.hpp"
#include "stage/output/xv-displayer.hpp"
#include "include/logging.h"
//#include "lib/format-cout.hpp"
#include <gdk/gdkx.h>
namespace stage {
namespace output {
namespace {
const uint32_t FORMAT_ID_YUY2 = 0x32595559;
}
XvDisplayer::XvDisplayer(Gtk::Widget& drawing_area
,int width, int height)
,uint width, uint height)
: Displayer{width,height}
, gotPort{false}
, drawingArea_{drawing_area}
, xvImage{nullptr}
{
REQUIRE (width > 0);
REQUIRE (height > 0);
REQUIRE (videoWidth > 0);
REQUIRE (videoHeight > 0);
INFO(stage, "Trying XVideo at %d x %d", width, height);
INFO(stage, "Trying XVideo at %d x %d", videoWidth, videoHeight);
shmInfo.shmaddr = NULL;
Glib::RefPtr<Gdk::Window> area_window = drawing_area.get_window();
Glib::RefPtr<Gdk::Window> area_window = drawingArea_.get_window();
window = GDK_WINDOW_XID (area_window->gobj());
display = GDK_WINDOW_XDISPLAY (area_window->gobj());
@ -82,7 +87,7 @@ namespace output {
( list[ i ].id >> 16 ) & 0xff,
( list[ i ].id >> 24 ) & 0xff,
( list[ i ].format == XvPacked ) ? "packed" : "planar" );
if ( list[ i ].id == 0x32595559 && !gotPort )
if ( list[ i ].id == FORMAT_ID_YUY2 && !gotPort )
gotPort = true;
}
@ -143,7 +148,7 @@ namespace output {
memset(&values, 0, sizeof(XGCValues));
gc = XCreateGC( display, window, 0, NULL );
xvImage = ( XvImage * ) XvShmCreateImage( display, grabbedPort, 0x32595559, 0, width, height, &shmInfo );
xvImage = ( XvImage * ) XvShmCreateImage( display, grabbedPort, FORMAT_ID_YUY2, 0, videoWidth, videoHeight, &shmInfo );
shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 );
if (shmInfo.shmid < 0) {
@ -210,14 +215,19 @@ namespace output {
if (xvImage != NULL)
{
REQUIRE(display != NULL);
REQUIRE (display != NULL);
REQUIRE (drawingArea_.get_mapped());
int org_x = 0, org_y = 0, destW = 0, destH = 0;
calculateVideoLayout(
drawingArea_.get_width(),
drawingArea_.get_height(),
org_x, org_y, destW, destH );
auto spaceAlloc = drawingArea_.get_allocation();
org_x += spaceAlloc.get_x();
org_y += spaceAlloc.get_y();
memcpy (xvImage->data, image, xvImage->data_size);
XvShmPutImage (display, grabbedPort, window, gc, xvImage,

View file

@ -52,14 +52,11 @@ namespace output {
public:
/**
* Constructor
* @param drawing_area The widget into which the video image will be
* drawn. This value must not be NULL.
* @param width The width of the video image in pixels. This value
* must be greater than zero.
* @param height The height of the video image in pixels. This value
* must be greater than zero.
* @param drawing_area The widget into which the video image will be drawn.
* @param width of the video image image to be displayed, in pixels.
* @param height of the video image in pixels to be displayed.
*/
XvDisplayer (Gtk::Widget& drawing_area, int width, int height);
XvDisplayer (Gtk::Widget& drawing_area, uint width, uint height);
~XvDisplayer();

View file

@ -130051,12 +130051,63 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="full-2"/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1746718103627" ID="ID_1187659462" MODIFIED="1746718152643" TEXT="...aber nur, wenn man die Maus &#xfc;ber dem Widget bewegt">
<icon BUILTIN="broken-line"/>
<node CREATED="1746753368642" ID="ID_907692574" MODIFIED="1746753406105" TEXT="wenn ich einen queue_redraw() f&#xfc;r jeden put() mache, wird unten schwarz dr&#xfc;bergezeichnet"/>
<node CREATED="1746753425155" ID="ID_893585016" MODIFIED="1746753650297" TEXT="wenn ich den schwarzen HIntergrund weglasse, ist es analog, aber mit default-Background"/>
<node CREATED="1746753577298" ID="ID_1381345463" MODIFIED="1746753640834" TEXT="wenn ich dagegen die CLASS_background vom VideoDisplayWidget weglasse...">
<node CREATED="1746753652389" ID="ID_1001449914" MODIFIED="1746753677932" TEXT="wird der gesamte Bereich des Display-panels nicht refreshed"/>
<node CREATED="1746753679035" ID="ID_1957359311" MODIFIED="1746753700917" TEXT="das hei&#xdf;t: was vorher dahinter war, bleibt stehen"/>
<node CREATED="1746753701678" ID="ID_371467731" MODIFIED="1746753713283" TEXT="aber wenn man das Fenster verschiebt, bleibt einfach M&#xfc;ll"/>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1746718116512" ID="ID_415171245" MODIFIED="1746718148895" TEXT="und die H&#xf6;he der Dekoration ist auch nicht korrekt eingerechnet">
<node CREATED="1746753406837" ID="ID_458597358" MODIFIED="1746753420111" TEXT="aber das Video updatet nur, wenn die Maus bewegt wird"/>
<node CREATED="1746753723320" ID="ID_1317517051" MODIFIED="1746753739591" TEXT="und zwar egal wo, es mu&#xdf; nur im Bereich des Lumiera-Fenster sein"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#330f69" CREATED="1746718116512" ID="ID_415171245" MODIFIED="1746756819258" TEXT="und die H&#xf6;he der Dekoration ist auch nicht korrekt eingerechnet">
<icon BUILTIN="broken-line"/>
<node CREATED="1746753745775" ID="ID_1490197751" MODIFIED="1746753762431" TEXT="genauer: es wird wohl das ganze XWindow als Koordinaten-Basis genommen">
<node CREATED="1746756246859" ID="ID_948265923" MODIFIED="1746756278756" TEXT="&#x27f9; man m&#xfc;&#xdf;te die Allokation des eigentlichen Image-Widgets mit ber&#xfc;cksichtigen"/>
<node CREATED="1746756291194" ID="ID_808564158" LINK="https://web.archive.org/web/20210306120056/https://developer.gnome.org/gtkmm/3.22/classGtk_1_1Widget.html#a67a286b9da91a83ee6016b479dad2341" MODIFIED="1746756310394" TEXT="Gtk::Widget::getAllocation">
<node CREATED="1746756337943" ID="ID_956508739" MODIFIED="1746756339042" TEXT="typedef Gdk::Rectangle Gtk::Allocation"/>
<node COLOR="#338800" CREATED="1746756776005" ID="ID_1382536900" MODIFIED="1746756792366" TEXT="Offset des Widgets in das Video-Display mitber&#xfc;cksichtigen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1746756918061" ID="ID_1884149717" MODIFIED="1746756934352" TEXT="kaum macht man&apos;s richtig, schon funktionierts">
<font NAME="SansSerif" SIZE="7"/>
</node>
</node>
</node>
<node CREATED="1746756014267" ID="ID_444628176" MODIFIED="1746756032086" TEXT="und es wird f&#xfc;r das gesamte XWindow die Compositing-Strategie angewendet">
<node CREATED="1746756054837" ID="ID_1371798971" MODIFIED="1746756061608" TEXT="wir setzen das Port-Attribute"/>
<node CREATED="1746756062309" ID="ID_1479032515" MODIFIED="1746756081453" TEXT="ich deute das so, da&#xdf; dieser Code ein Compositing per Color-Key macht"/>
<node CREATED="1746756083857" ID="ID_80824487" MODIFIED="1746756106802" TEXT="das w&#xe4;re die einfachste (uralt)-Methode, auf die XV stets zur&#xfc;ckfallen kann"/>
<node CREATED="1746756107974" ID="ID_34298329" MODIFIED="1746756233195" TEXT="zus&#xe4;tzlich kann XV mit einem Compositor verwendet werden (glaub ich)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
beziehe mich hier per Ged&#228;chtnis auf Sachverhalte, die ich irgenwann irgendwo mal gelesen habe; demnach kann XV mit irgend einer Art von &#187;Compositor&#171; zusammenarbeiten, notfalls aber seine sichtbare (clipping)-Region auch per Colour-Key herausfinden; dabei geht es um die Frage, welcher Teil des Videobildes tats&#228;chlich auf dem Desktop zu sehen ist, denn das Fenster k&#246;nnte partiell verdeckt sein
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#dda58c" COLOR="#5b280f" CREATED="1746756832085" ID="ID_853235588" MODIFIED="1746757025215" TEXT="&#x27f9; in den Grenzen dieses Demo-Codes nicht reparierbar">
<arrowlink COLOR="#db2739" DESTINATION="ID_682377255" ENDARROW="Default" ENDINCLINATION="179;8;" ID="Arrow_ID_438825790" STARTARROW="None" STARTINCLINATION="-4;66;"/>
<icon BUILTIN="button_cancel"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1746718129879" ID="ID_1760604400" MODIFIED="1746718147158" TEXT="und eine sonderbare durchsichtige Zone ist im GUI">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1746753315931" ID="ID_1431535426" MODIFIED="1746753343029" TEXT="diese umfa&#xdf;t die Kopfzeile des Docking-Pannel"/>
<node CREATED="1746753343975" ID="ID_1196127587" MODIFIED="1746753362511" TEXT="die Video-Anzeige beginnt ebenfalls in der Kopfzeile"/>
<node CREATED="1746756947014" ID="ID_716643169" MODIFIED="1746756974526" TEXT="Deutung">
<node CREATED="1746756975402" ID="ID_682377255" MODIFIED="1746757016772" TEXT="wir verwenden Colour-Keying auf dem ganzen zugeordneten XWindow">
<linktarget COLOR="#db2739" DESTINATION="ID_682377255" ENDARROW="Default" ENDINCLINATION="179;8;" ID="Arrow_ID_438825790" SOURCE="ID_853235588" STARTARROW="None" STARTINCLINATION="-4;66;"/>
</node>
<node CREATED="1746756977623" ID="ID_1960782604" MODIFIED="1746757001777" TEXT="und da das Dock beweglich ist, verwendet es wohl ein eigenes XWindow"/>
</node>
</node>
</node>
</node>