Re: [Spice-devel] How to use spice-streaming-agent properly?

2020-02-02 Thread Snir Sheriber



On 1/25/20 2:58 PM, ole-kru...@yandex.ru wrote:

Hello dear devs,

our host has libspice-server1 0.14.2, qemu-kvm 4.1, libvirt 5.0.0 with "ramfb" 
option for mediated devices enabled,  NVIDIA GRID GPU. We'd like to stream 
GPU-accelerated video from Linux guests. spice-streaming-agent+gst-plugin is built and 
sends video encoded to H.264 by NVENC codec from guest. Quality of video is very good, 
bitrate and presets can be set by cmdline parameters.
Guest's video config consists of hostdev mediated device which corresponds to NVIDIA vGPU 
and second "none", which is needed because of libvirt 5.0 does not allow guests 
with only mediated device set.
There are two showstoppers:


Hi,

Nice to hear that you are using it with nvenc and having fairly good 
results. Unfortunately
Libvirt does not have the relevant bits to support spice-streaming-agent 
yet.


But I know you should be able to workaround it by setting also qxl (i 
did not try with ramfb):



   
   


max_outputs=1 is required to avoid some bug which is fixed on upstream 
spice server.



1) when enabled, the video stream creates a new window in remote-viewer (versions 
6.0-8.0) instead of replace old one. Old SPICE traffic is sent along with H264 stream, 
consuming network and client CPU significantly. When this "old main" trafficis 
is disabled in remote-viewer, video streaming stops too. Remmina (all new builds 
including 2020.01.08) does not show this window at all.


I assume this is due to the ramfb. This was not tested yet with the 
spice-streaming-agent setup.


With the above suggested setup (& ramfb disabled) it will also be in 
another window but the first

window should not really be active, you can close it manually.


2) No mouse or keyboard control is available in window with video stream, so it can be 
used just like some "TV set" but all actions should be done in old window. 
Guest logs say about some mouse activity on unknown display when mouse buttons are 
pressed on tthis window.


Should also work with this setup.

Snir.



Can that be fixed? Can spice-streaming-agent replace main display channel?

Thanks in advance!
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel



___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel


[Spice-devel] [PATCH spice-gtk 1/2] gstreamer: Use the element-setup signal instead of deep-element-added

2019-09-24 Thread Snir Sheriber
Its functionally is equivalent to connecting to the deep-element-added
signal, but a bit more convenient

Signed-off-by: Snir Sheriber 
---
 src/channel-display-gst.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 6fccf62..437328b 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -471,8 +471,7 @@ sink_event_probe(GstPad *pad, GstPadProbeInfo *info, 
gpointer data)
 
 /* This function is called to used to set a probe on the sink */
 static void
-deep_element_added_cb(GstBin *pipeline, GstBin *bin, GstElement *element,
-  SpiceGstDecoder *decoder)
+element_setup_cb(GstElement *pipeline, GstElement *element, SpiceGstDecoder 
*decoder)
 {
 /* Attach a probe to the sink to update the statistics */
 if (GST_IS_BASE_SINK(element)) {
@@ -543,7 +542,7 @@ static gboolean create_pipeline(SpiceGstDecoder *decoder)
 #endif
 }
 
-g_signal_connect(playbin, "deep-element-added", 
G_CALLBACK(deep_element_added_cb), decoder);
+g_signal_connect(playbin, "element-setup", G_CALLBACK(element_setup_cb), 
decoder);
 g_signal_connect(playbin, "source-setup", G_CALLBACK(app_source_setup), 
decoder);
 
 g_object_set(playbin,
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-gtk 2/2] gstreamer: add debug message for each element added to pipeline

2019-09-24 Thread Snir Sheriber
Signed-off-by: Snir Sheriber 
---

This helps to debug plugins load related issues
---
 src/channel-display-gst.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 437328b..16bfa37 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -473,6 +473,10 @@ sink_event_probe(GstPad *pad, GstPadProbeInfo *info, 
gpointer data)
 static void
 element_setup_cb(GstElement *pipeline, GstElement *element, SpiceGstDecoder 
*decoder)
 {
+GstElementFactory *f = gst_element_get_factory (element);
+
+SPICE_DEBUG("A new element was added to Gstreamer's pipeline (%s)",
+f ? GST_OBJECT_NAME(f) : GST_OBJECT_NAME(element));
 /* Attach a probe to the sink to update the statistics */
 if (GST_IS_BASE_SINK(element)) {
 GstPad *pad = gst_element_get_static_pad(element, "sink");
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent] gst-plugin: Changing framerate crash when ximagesrc is used

2019-09-19 Thread Snir Sheriber
When XLIB_CAPTURE is set to 0 and framerate is set to anything
other than 25 streaming-agent crashes

This is a regrerssion caused by e0cf764baff9d678a6e75916457300d1ff39b169
Fixing it is done by adding the framerate value to convertion caps

Signed-off-by: Snir Sheriber 
---
 src/gst-plugin.cpp | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 70bc6c8..922b90d 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -237,7 +237,10 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 gst_bin_add(bin, sink);

 GstCapsUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));
-link = gst_element_link(capture.get(), convert.get()) &&
+GstCapsUPtr convert_caps(gst_caps_new_simple("video/x-raw",
+ "framerate", 
GST_TYPE_FRACTION, settings.fps, 1,
+ nullptr));
+link = gst_element_link_filtered(capture.get(), convert.get(), 
convert_caps.get()) &&
gst_element_link_filtered(convert.get(), encoder.get(), caps.get()) 
&&
gst_element_link_filtered(encoder.get(), sink.get(), 
sink_caps.get());
 if (!link) {
-- 
2.21.0
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaminh-agent 2/3] mjpeg-fallback: Use Xlib capture helper

2019-09-15 Thread Snir Sheriber


On 8/28/19 5:48 PM, Frediano Ziglio wrote:

---
  src/Makefile.am|  4 
  src/mjpeg-fallback.cpp | 38 +-
  2 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 0133bf5..31b8af1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,7 @@ AM_CPPFLAGS = \
$(X11_CFLAGS) \
$(XFIXES_CFLAGS) \
$(XRANDR_CFLAGS) \
+   $(XEXT_CFLAGS) \
$(NULL)
  
  AM_CFLAGS = \

@@ -56,6 +57,7 @@ spice_streaming_agent_LDADD = \
$(X11_LIBS) \
$(XFIXES_LIBS) \
$(XRANDR_LIBS) \
+   $(XEXT_LIBS) \
$(JPEG_LIBS) \
$(NULL)
  
@@ -77,6 +79,8 @@ spice_streaming_agent_SOURCES = \

utils.cpp \
utils.hpp \
x11-display-info.cpp \
+   xlib-capture.cpp \
+   xlib-capture.hpp \
$(NULL)
  
  if HAVE_GST

diff --git a/src/mjpeg-fallback.cpp b/src/mjpeg-fallback.cpp
index 03247a1..a43825b 100644
--- a/src/mjpeg-fallback.cpp
+++ b/src/mjpeg-fallback.cpp
@@ -16,6 +16,7 @@
  #include 
  #include 
  #include 
+#include "xlib-capture.hpp"
  
  using namespace spice::streaming_agent;
  
@@ -44,11 +45,10 @@ public:

  private:
  MjpegSettings settings;
  Display *const dpy;
+XlibCapture *xc;

unique_ptr ?


Hi,

Just noticed, if it's a unique_ptr connection with X may be destroyed before
that (by ~MjpegFrameCapture)

Snir.



  
  std::vector frame;
  
-// last frame sizes

-int last_width = -1, last_height = -1;
  // last time before capture
  uint64_t last_time = 0;
  };
@@ -58,19 +58,21 @@ private:
  MjpegFrameCapture::MjpegFrameCapture(const MjpegSettings& settings):
  settings(settings),dpy(XOpenDisplay(nullptr))
  {
-if (!dpy)
+if (!dpy) {
  throw std::runtime_error("Unable to initialize X11");
+}
+xc = new XlibCapture(dpy);
  }
  
  MjpegFrameCapture::~MjpegFrameCapture()

  {
+delete xc;
  XCloseDisplay(dpy);
  }
  
  void MjpegFrameCapture::Reset()

  {
  frame.clear();
-last_width = last_height = -1;
  }
  
  FrameInfo MjpegFrameCapture::CaptureFrame()

@@ -100,34 +102,20 @@ FrameInfo MjpegFrameCapture::CaptureFrame()
  }
  }
  
-int screen = XDefaultScreen(dpy);

-
-Window win = RootWindow(dpy, screen);
+XImg *image = xc->capture();
  

The capture returns a NULL value on failure, better to check it
(was "// TODO handle errors").


-XWindowAttributes win_info;
-XGetWindowAttributes(dpy, win, &win_info);
+bool is_first = image->new_resolution();
  
-bool is_first = false;

-if (win_info.width != last_width || win_info.height != last_height) {
-last_width = win_info.width;
-last_height = win_info.height;
-is_first = true;
-}
+info.size.width = image->width();
+info.size.height = image->height();
  
-info.size.width = win_info.width;

-info.size.height = win_info.height;
-
-int format = ZPixmap;
-// TODO handle errors
-XImage *image = XGetImage(dpy, win, win_info.x, win_info.y,
-  win_info.width, win_info.height, AllPlanes,
format);
  
  // TODO handle errors

  // TODO multiple formats (only 32 bit)
-write_JPEG_file(frame, settings.quality, (uint8_t*) image->data,
-image->width, image->height);
+write_JPEG_file(frame, settings.quality, (uint8_t*) image->get_data(),
+image->width(), image->height());
  
-image->f.destroy_image(image);

+delete image;
  
  info.buffer = &frame[0];

  info.buffer_size = frame.size();

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaming-agent 1/3] Add Xlib capture helper files

2019-09-11 Thread Snir Sheriber

Hi,


Sorry for the late replay


On 8/28/19 5:44 PM, Frediano Ziglio wrote:

The Xlib capture helper provides a wrapping class for XImage, Display
information and other capturing related functionalities which allows
to use unified and simple API for screen capturing using X.
This also utilize the X MIT-SHM extension which improves capturing
speed, hence, xext is required.
---

The original idea was just to use the X ancient MIT-SHM extension which
reduce CPU utilization significantly when using Xlib capturing.
Since this capturing method is currently used by two different plugins
it was suggested to use one common class for that, this class is added
by this patch and the 2 following patches makes the existing plugins
to use this class.

If you have any other suggestions or comments please do ;)


It's not clear why the RFC. From the comment looks like you want them.
Maybe you are not sure about the state of the patches?


I do want them but i also want comments ;)





---
  configure.ac |   1 +
  src/xlib-capture.cpp | 169 +++
  src/xlib-capture.hpp |  53 ++
  3 files changed, 223 insertions(+)
  create mode 100644 src/xlib-capture.cpp
  create mode 100644 src/xlib-capture.hpp

diff --git a/configure.ac b/configure.ac
index 1c7788b..3220e27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,7 @@ PKG_CHECK_MODULES(DRM, libdrm)
  PKG_CHECK_MODULES(X11, x11)
  PKG_CHECK_MODULES(XFIXES, xfixes)
  PKG_CHECK_MODULES(XRANDR, xrandr)
+PKG_CHECK_MODULES(XEXT, xext)
  
  PKG_CHECK_MODULES(JPEG, libjpeg, , [

  AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
diff --git a/src/xlib-capture.cpp b/src/xlib-capture.cpp
new file mode 100644
index 000..7837ee2
--- /dev/null
+++ b/src/xlib-capture.cpp
@@ -0,0 +1,169 @@
+/* A helper classes that wraps X display information XImage capturing
functions
+ *
+ * \copyright
+ * Copyright 2019 Red Hat Inc. All rights reserved.
+ */
+
+#include 
+#include 
+#include "xlib-capture.hpp"
+
+namespace spice {
+namespace streaming_agent {
+
+/ XImg Class Impl ***/
+
+XImg::XImg(XImage *x_image, bool is_shm, bool new_res) {

style: bracket on next line


+ this->x_image = x_image;
+ this->x_shm = is_shm;
+ this->new_res = new_res;

Better to use class initialized, even if in this case won't change
much.


What do you mean by class initialized?

XImg(XImage *x_image, bool is_shm, bool new_res): x_image(x_image), 
x_shm(is_shm),new_res(new_res)?







+}
+
+XImg::~XImg() {
+if (!x_shm) {
+XDestroyImage(x_image);
+} // else the XlibCapture will destroy it
+}
+
+char *XImg::get_data() {
+return x_image->data;
+}
+
+int XImg::height() {
+return x_image->height;
+}
+
+int XImg::width() {
+return x_image->width;
+}
+
+int XImg::data_size() {
+return x_image->height * x_image->bytes_per_line;
+}
+
+bool XImg::new_resolution() {
+   return new_res;
+}
+

I would inline these in the header. Also I would add const, they don't
allow to change the object.

This "new_resolution" does not apply to the "provides a wrapping class for
XImage", are more related to capture interface. Maybe "XCapturedImg" as name
of the class?


+/** XlibCapture Class Impl ***/
+
+static int (*previous_x_err_handler)(Display *display, XErrorEvent *event) =
0;

better "= nullptr" or at least "= NULL" (although 0 for historic reason works).


+static bool xerror = false;
+
+/* This is used mainly to silence x error in case of resolution change */
+static int x_err_handler(Display *display, XErrorEvent *event) {
+//TODO: print some error information ?
+switch (event->error_code) {
+case BadAccess:

style: too indented.


+case BadMatch:
+xerror = true;
+return 0;
+default:
+return previous_x_err_handler(display, event);
+}
+}
+
+void XlibCapture::init_xshm() {
+Visual *visual = DefaultVisual(display, screen);
+unsigned int depth = DefaultDepth(display, screen);
+XWindowAttributes win_info;
+
+xshm_enabled = false;
+xerror = false;
+// Create Shared Memory XImage
+XGetWindowAttributes(display, win, &win_info); // update attributes
+xshm_image = XShmCreateImage(display, visual, depth, ZPixmap, nullptr,
+ &shm_info, win_info.width,
win_info.height);
+if (!xshm_image) {
+return;
+}
+// Allocate shm buffer
+int shm_id = shmget(IPC_PRIVATE, xshm_image->bytes_per_line *
xshm_image->height, IPC_CREAT|0777);
+if (shm_id == -1) {
+XDestroyImage(xshm_image);

I suppose you want to reset xshm_image too to avoid dandling pointers.


xshm_image?





+return;
+}
+
+// Attach share memory bufer
+void *shm_addr = shmat(shm_id, nullptr, 0);
+if (shm_addr == (void*)-1) {
+XDestroyImage(xshm_image);
+shmctl(shm_id, IPC_RMID, nullptr);
+return;
+

Re: [Spice-devel] [PATCH spice-gtk 2/3] .gitlab-ci: Save artifacts for copr builds use and deploy

2019-09-10 Thread Snir Sheriber

Hi,


On 9/9/19 6:54 PM, Frediano Ziglio wrote:

deploy is done by triggering copr's webhook so copr will
get the artifacts and generate a build.
---

This is another suggestion to integrate deployment to copr
The flow is as follow:
- Successful gitlab-ci build will generate tarball and spec file
   as accessible artifacts
- once the linux build completed the deploy job will trigger the
   copr's project custom webhook
- Triggering the webhook will cause copr to execute its pre-defined
   custom source script which will download the artifacts and
   let the build in copr to begin

Three steps are needed in order to make this work:
1. having this two patches
2. set a custom source script in copr to just get the tarball and spec
for example:
  # only getting the specfile and tarball artifacts, locate in outputdir
  and edit
  # release number
  curl -L --output artifacts.zip
  
"https://gitlab.freedektop.org/spice/spice-gtk/-/jobs/artifacts/master/download?job=fedora";
  unzip -j artifacts.zip '*.spec'
  unzip -j artifacts.zip '*.tar.xz'
  sed -i -E
  "s/(^Release:[[:space:]]*)([^%]*)/\1`date+'%Y%m%d%H%M.spice.latest'`/"
  *.spec

Why you need this? I mean, is not good the version generated by the CI?



Should be fine since the version is 
[current-version].[num-of-commits-since-last-tag]
I used it just for convenience so once it's installed naming will 
provide some build

info on the non-standard fedora\rhel pkg.





3. set in gitlab the COPR_ID_UUID environment variable to the package's
/ (this variable needs to be set in this
"/" form and combination due to some gitlab
environment variables limitations. This variable should be masked
so it cannot be used by a malicious entity)


I suppose it's used as a kind of security. Is the COPR_ID secret?


Yep





Pros and cons in regard to the previous suggestion
(https://patchwork.freedesktop.org/series/65881/)
PROS:
* Only minor changes are required
* .copr/Makefile is not needed
* gitlab-ci build artifacts are used, not need to build again
* less scripting hacks

CONS:
* gitlab + copr + code minor configurations are required
* customized configurations (non standard)

What do you mean with this? Which component configuration are you referring to?



Using the custom webhook (instead of the gitlab webhook) and
using the copr custom script instead of other method





* The environment variable trick is a bit hacky


Is more for security it seems to me.



Yes, but i found the combination of id/uuid a bit tricky




I like this solution better than previous. Part of the comments above
would be good to go to the commit message.
Looks like this series is a bit RFC.

Where's patch 3/3 ?



Oh, forget to to edit this, it is not needed
It's just another patch fixing spice-protocol clone address so it
will work on my private repo

Snir.





---
  .gitlab-ci.yml | 23 +++
  1 file changed, 23 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e2d1c55..826e925 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,9 +20,12 @@ variables:
mingw64-usbredir mingw32-usbredir
  
  fedora:

+  stage: build
artifacts:
  paths:
- build-*/meson-logs/*.txt
+  - build-default/meson-dist/spice-gtk*.tar.xz
+  - build-default/*.spec
  when: always
  expire_in: 1 week
  
@@ -33,6 +36,8 @@ fedora:

  - ninja -C build-spice-protocol install
  
script:

+# Use version format as follows
[current-version].[num-of-commits-since-last-tag]
+- echo $(git describe --match=v\* --abbrev=0 | sed "s/v// ;
s/$/./")$(git rev-list $(git describe --abbrev=0)..HEAD | wc -l) >
.tarball-version
  - meson --buildtype=release build-default --werror
  # Meson does not update submodules recursively
  - git submodule update --init --recursive
@@ -48,6 +53,7 @@ fedora:
  - ninja -C build-feat-disabled test
  
  windows:

+  stage: build
artifacts:
  paths:
- build-win64/meson-logs/*.txt
@@ -67,3 +73,20 @@ windows:
  - mkdir build-win64 && cd build-win64
  - mingw64-meson --buildtype=release -Dgtk_doc=disabled --werror
  - ninja install
+
+fedora:deploy:
+  stage: deploy
+  needs: ["fedora"]
+  only:
+variables:
+# Run this stage only if COPR_ID_UUID is defined
+# COPR_ID_UUID is gitlab VARIABLE that should be set to this string:
"/"
+- $COPR_ID_UUID
+  script:
+# This is a custom webhook which can triger a custom source script (set
in copr) that

typo: triger -> trigger


+# should just download the specfile and tarball from the artifacts url.
+#  Create a copr's custom source script:
+#
https://docs.pagure.org/copr.copr/custom_source_method.html#custom-source-method
+#  Get artifacts created by this gitlab ci:
+#
https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html#downloading-the-latest-artifacts
+- curl -X POST
https://copr.fedorainfracloud.org/we

[Spice-devel] [PATCH spice-gtk 1/3] Generate spec file from spec.in

2019-09-09 Thread Snir Sheriber
---
 meson.build   |  11 +++
 spice-gtk.spec.in | 190 ++
 2 files changed, 201 insertions(+)
 create mode 100644 spice-gtk.spec.in

diff --git a/meson.build b/meson.build
index 171a3f6..7ececd7 100644
--- a/meson.build
+++ b/meson.build
@@ -407,3 +407,14 @@ if spice_gtk_has_gtk
  requires : 'spice-client-glib-2.0 gtk+-3.0 >= 
@0@'.format(gtk_version_required),
  variables : 'exec_prefix=${prefix}')
 endif
+
+#
+# spec file
+#
+conf_data = configuration_data()
+conf_data.set('version', meson.project_version())
+conf_data.set('release', '1')
+
+configure_file(input : 'spice-gtk.spec.in',
+   output : 'spice-gtk.spec',
+   configuration : conf_data)
diff --git a/spice-gtk.spec.in b/spice-gtk.spec.in
new file mode 100644
index 000..dd31f17
--- /dev/null
+++ b/spice-gtk.spec.in
@@ -0,0 +1,190 @@
+#define _version_suffix
+
+Name:   spice-gtk
+Version:@version@
+Release:@release@%{?dist}
+Summary:A GTK+ widget for SPICE clients
+
+License:LGPLv2+
+URL:https://www.spice-space.org/
+#VCS:   git:git://anongit.freedesktop.org/spice/spice-gtk
+Source0:%{name}-%{version}%{?_version_suffix}.tar.xz
+
+BuildRequires: git-core
+BuildRequires: meson
+BuildRequires: intltool
+BuildRequires: usbredir-devel >= 0.7.1
+BuildRequires: libusb1-devel >= 1.0.16
+BuildRequires: pixman-devel libjpeg-turbo-devel
+BuildRequires: opus-devel
+BuildRequires: zlib-devel
+BuildRequires: cyrus-sasl-devel
+BuildRequires: libcacard-devel
+BuildRequires: gobject-introspection-devel
+BuildRequires: libacl-devel
+%if ! 0%{?flatpak}
+BuildRequires: polkit-devel
+%endif
+BuildRequires: gtk-doc
+BuildRequires: vala
+BuildRequires: usbutils
+BuildRequires: libsoup-devel >= 2.49.91
+BuildRequires: libphodav-devel
+BuildRequires: lz4-devel
+BuildRequires: gtk3-devel
+BuildRequires: json-glib-devel
+BuildRequires: spice-protocol >= 0.12.15
+BuildRequires: gstreamer1-devel >= 1.10
+BuildRequires: gstreamer1-plugins-base-devel >= 1.10
+BuildRequires: python3-six
+BuildRequires: python3-pyparsing
+BuildRequires: openssl-devel
+BuildRequires: gnupg2
+
+Obsoletes: spice-gtk-python < 0.32
+
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description
+Client libraries for SPICE desktop servers.
+
+%package -n spice-glib
+Summary: A GObject for communicating with Spice servers
+
+%description -n spice-glib
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+%package -n spice-glib-devel
+Summary: Development files to build Glib2 applications with spice-glib-2.0
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: glib2-devel
+
+%description -n spice-glib-devel
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+Libraries, includes, etc. to compile with the spice-glib-2.0 libraries
+
+%package -n spice-gtk3
+Summary: A GTK3 widget for SPICE clients
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description -n spice-gtk3
+spice-client-glib-3.0 is a SPICE client library for Gtk3.
+
+%package -n spice-gtk3-devel
+Summary: Development files to build GTK3 applications with spice-gtk-3.0
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+Requires: spice-glib-devel%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: gtk3-devel
+Obsoletes: spice-gtk-devel < 0.32
+
+%description -n spice-gtk3-devel
+spice-client-gtk-3.0 provides a SPICE viewer widget for GTK3.
+
+Libraries, includes, etc. to compile with the spice-gtk3 libraries
+
+%package -n spice-gtk3-vala
+Summary: Vala bindings for the spice-gtk-3.0 library
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+Requires: spice-gtk3-devel%{?_isa} = %{version}-%{release}
+
+%description -n spice-gtk3-vala
+A module allowing use of the spice-gtk-3.0 widget from vala
+
+%package tools
+Summary: Spice-gtk tools
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+
+%description tools
+Simple clients for interacting with SPICE servers.
+spicy is a client to a SPICE desktop server.
+spicy-screenshot is a tool to capture screen-shots of a SPICE desktop.
+
+
+%prep
+%autosetup -S git_am
+
+
+%build
+
+# meson macro has --auto-features=enabled
+# gstreamer should be enough, may be deprecated in the future
+%global mjpegflag -Dbuiltin-mjpeg=false
+# spice-common doesn't use auto feature yet
+%global celt051flag -Dcelt051=disabled
+# pulse is deprecated upstream
+%global pulseflag -Dpulse=disabled
+
+%meson \
+  %{mjpegflag} \
+  %{celt051flag} \
+  %{pulseflag} \
+%if 0%{?flatpak}
+  -Dpolkit=disabled
+%else
+  -Dusb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/
+%endif
+
+%meson_build
+
+
+%check
+%meson_test
+
+
+%install
+%meson_install
+
+
+%find_lang %{name}
+
+%ldconfig_scriptlets
+%ldconfig_scriptlets -n spice-glib
+%ldconfig_scriptlets -n spice-gtk3
+
+
+%files
+%doc AUTHORS
+%doc COPYING
+%doc README.md
+%doc CHANGELOG.md
+%{_mandir}/man1/spic

[Spice-devel] [PATCH spice-gtk 2/3] .gitlab-ci: Save artifacts for copr builds use and deploy

2019-09-09 Thread Snir Sheriber
deploy is done by triggering copr's webhook so copr will
get the artifacts and generate a build.
---

This is another suggestion to integrate deployment to copr
The flow is as follow:
- Successful gitlab-ci build will generate tarball and spec file
  as accessible artifacts
- once the linux build completed the deploy job will trigger the
  copr's project custom webhook
- Triggering the webhook will cause copr to execute its pre-defined
  custom source script which will download the artifacts and
  let the build in copr to begin

Three steps are needed in order to make this work:
1. having this two patches
2. set a custom source script in copr to just get the tarball and spec
   for example:
 # only getting the specfile and tarball artifacts, locate in outputdir and 
edit
 # release number
 curl -L --output artifacts.zip  
"https://gitlab.freedektop.org/spice/spice-gtk/-/jobs/artifacts/master/download?job=fedora";
 unzip -j artifacts.zip '*.spec'
 unzip -j artifacts.zip '*.tar.xz'
 sed -i -E 
"s/(^Release:[[:space:]]*)([^%]*)/\1`date+'%Y%m%d%H%M.spice.latest'`/" *.spec
3. set in gitlab the COPR_ID_UUID environment variable to the package's
   / (this variable needs to be set in this
   "/" form and combination due to some gitlab
   environment variables limitations. This variable should be masked
   so it cannot be used by a malicious entity)


Pros and cons in regard to the previous suggestion
(https://patchwork.freedesktop.org/series/65881/)
PROS:
* Only minor changes are required
* .copr/Makefile is not needed
* gitlab-ci build artifacts are used, not need to build again
* less scripting hacks

CONS:
* gitlab + copr + code minor configurations are required
* customized configurations (non standard)
* The environment variable trick is a bit hacky

---
 .gitlab-ci.yml | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e2d1c55..826e925 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,9 +20,12 @@ variables:
   mingw64-usbredir mingw32-usbredir
 
 fedora:
+  stage: build
   artifacts:
 paths:
   - build-*/meson-logs/*.txt
+  - build-default/meson-dist/spice-gtk*.tar.xz
+  - build-default/*.spec
 when: always
 expire_in: 1 week
 
@@ -33,6 +36,8 @@ fedora:
 - ninja -C build-spice-protocol install
 
   script:
+# Use version format as follows 
[current-version].[num-of-commits-since-last-tag]
+- echo $(git describe --match=v\* --abbrev=0 | sed "s/v// ; s/$/./")$(git 
rev-list $(git describe --abbrev=0)..HEAD | wc -l) > .tarball-version
 - meson --buildtype=release build-default --werror
 # Meson does not update submodules recursively
 - git submodule update --init --recursive
@@ -48,6 +53,7 @@ fedora:
 - ninja -C build-feat-disabled test
 
 windows:
+  stage: build
   artifacts:
 paths:
   - build-win64/meson-logs/*.txt
@@ -67,3 +73,20 @@ windows:
 - mkdir build-win64 && cd build-win64
 - mingw64-meson --buildtype=release -Dgtk_doc=disabled --werror
 - ninja install
+
+fedora:deploy:
+  stage: deploy
+  needs: ["fedora"]
+  only:
+variables:
+# Run this stage only if COPR_ID_UUID is defined
+# COPR_ID_UUID is gitlab VARIABLE that should be set to this string: 
"/"
+- $COPR_ID_UUID
+  script:
+# This is a custom webhook which can triger a custom source script (set in 
copr) that
+# should just download the specfile and tarball from the artifacts url.
+#  Create a copr's custom source script:
+#   
https://docs.pagure.org/copr.copr/custom_source_method.html#custom-source-method
+#  Get artifacts created by this gitlab ci:
+#   
https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html#downloading-the-latest-artifacts
+- curl -X POST 
https://copr.fedorainfracloud.org/webhooks/custom/$COPR_ID_UUID/spice-gtk/
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [spice-gtk v1 2/6] display-gst: rely on SpiceSession init of GStreamer

2019-09-09 Thread Snir Sheriber

Hi,

On 9/9/19 12:01 PM, Victor Toso wrote:

Hi,

On Sun, Sep 08, 2019 at 04:25:32PM +0300, Snir Sheriber wrote:

Hi,


On 9/2/19 7:04 PM, Victor Toso wrote:

From: Victor Toso 

This means we can drop gstvideo_init() function and replace its calls
with gst_is_initialized().

Signed-off-by: Victor Toso 
---
   src/channel-display-gst.c | 23 +--
   1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 6fccf62..a34b5d0 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -748,22 +748,6 @@ static gboolean spice_gst_decoder_queue_frame(VideoDecoder 
*video_decoder,
   return TRUE;
   }
-static gboolean gstvideo_init(void)
-{
-static int success = 0;
-if (!success) {
-GError *err = NULL;
-if (gst_init_check(NULL, NULL, &err)) {
-success = 1;
-} else {
-spice_warning("Disabling GStreamer video support: %s", 
err->message);
-g_clear_error(&err);
-success = -1;
-}
-}
-return success > 0;
-}
-
   G_GNUC_INTERNAL
   VideoDecoder* create_gstreamer_decoder(int codec_type, display_stream 
*stream)
   {
@@ -771,7 +755,7 @@ VideoDecoder* create_gstreamer_decoder(int codec_type, 
display_stream *stream)
   g_return_val_if_fail(VALID_VIDEO_CODEC_TYPE(codec_type), NULL);
-if (gstvideo_init()) {
+if (gst_is_initialized()) {

Since the logical thing to do is usually to initialize
gstreamer once you start using it

Why? GStreamer is a library and I'd say the init is to be called
early on because that would deal with command line options,
environment variables etc. No extra delay on initializing this
kind of thing when we want to create a pipeline for video/audio
processing for instance is also valid argument.



Yes, i get it , just mentioned it as the reason for adding
the comment so that if someone will look at gstreamer's
code he will know he wouldn't find the initialization there
but in the session code :)

Snir.





i would add a comment it's now initialized by the session (if
not externally)

(also on gstaudio)

Ok, no problem. Thanks!


Snir.


   decoder = g_new0(SpiceGstDecoder, 1);
   decoder->base.destroy = spice_gst_decoder_destroy;
   decoder->base.reschedule = spice_gst_decoder_reschedule;
@@ -820,7 +804,10 @@ gboolean gstvideo_has_codec(int codec_type)
   GstCaps *caps;
   GstElementFactoryListType type;
-g_return_val_if_fail(gstvideo_init(), FALSE);
+if (!gst_is_initialized()) {
+return FALSE;
+}
+
   g_return_val_if_fail(VALID_VIDEO_CODEC_TYPE(codec_type), FALSE);
   type = GST_ELEMENT_FACTORY_TYPE_DECODER |

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [spice-gtk v1 6/6] RFC: test: session: gstreamer init by us or client

2019-09-08 Thread Snir Sheriber

HI,

On 9/2/19 7:04 PM, Victor Toso wrote:

From: Victor Toso 

Does not work properly just because gst_is_initialized() checks if
gst_init() or gst_check_init() was ever called but it does not
consider if gst_deinit() was called too. I'm sending this RFC to check
if should be added or wait till feedback on upstream about the API,
that is, I have a downstream patch that gst_is_initialized() would
return FALSE if gst_deinit() was called ...



Maybe should also be mentioned as comment in the code




Signed-off-by: Victor Toso 
---
  tests/session.c | 49 +
  1 file changed, 49 insertions(+)

diff --git a/tests/session.c b/tests/session.c
index 8208016..8e1814e 100644
--- a/tests/session.c
+++ b/tests/session.c
@@ -1,3 +1,6 @@
+#include 
+#include 
+
  #include 
  
  typedef struct {

@@ -333,6 +336,50 @@ static void test_session_uri_unix_good(void)
  test_session_uri_good(tests, G_N_ELEMENTS(tests));
  }
  
+static void session_init_test_on_gst(bool should_init)

+{
+
+if (should_init) {
+GError *err = NULL;
+gst_init_check(NULL, NULL, &err);
+g_assert_no_error(err);
+g_assert_true(gst_is_initialized());
+} else if (gst_is_initialized()) {



Is this likely to happen?



+#if 0
+/* Not working for now, gst_is_initialized() return TRUE also if
+ * gst_deinit() was called */
+gst_deinit();


also documentation of gst_deinit mention:

"After this call GStreamer (including this method) should not be used 
anymore."




+g_assert_false(gst_is_initialized());
+#endif
+}
+
+SpiceSession *session = spice_session_new();
+g_assert_true(gst_is_initialized());
+g_object_unref(session);
+if (should_init) {
+g_assert_true(gst_is_initialized());
+gst_deinit();
+#if 0
+g_assert_false(gst_is_initialized());
+#endif
+} else {
+#if 0
+/* Even if gst_deinit() is called, returns TRUE below */
+g_assert_false(gst_is_initialized());
+#endif
+}
+}
+
+static void test_session_gst_init_by_us(void)
+{
+session_init_test_on_gst(true);
+}
+
+static void test_session_gst_init_by_client(void)
+{
+session_init_test_on_gst(false);
+}
+


I find it a bit confusing, what about init_by_session and init_by_test
(or maybe init_externally and internally)

Oh, and the rest of the patches i didn't comment on looks good to me :)

Snir.



  int main(int argc, char* argv[])
  {
  g_test_init(&argc, &argv, NULL);
@@ -341,6 +388,8 @@ int main(int argc, char* argv[])
  g_test_add_func("/session/good-ipv4-uri", test_session_uri_ipv4_good);
  g_test_add_func("/session/good-ipv6-uri", test_session_uri_ipv6_good);
  g_test_add_func("/session/good-unix", test_session_uri_unix_good);
+g_test_add_func("/session/gstreamer/init-by-us", 
test_session_gst_init_by_us);
+g_test_add_func("/session/gstreamer/init-by-client", 
test_session_gst_init_by_client);
  
  return g_test_run();

  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [spice-gtk v1 4/6] session: gst_deinit() GStreamer if we initialize it

2019-09-08 Thread Snir Sheriber

Hi,

On 9/2/19 7:04 PM, Victor Toso wrote:

From: Victor Toso 

Let's gst_deinit() if we initialize it for the same rationale pointed out
in 0381e62 "spicy: Add call of gst_deinit at program exit" in
2017-10-20 by Christophe de Dinechin 

Signed-off-by: Victor Toso 
---
  src/spice-session.c | 8 
  1 file changed, 8 insertions(+)

diff --git a/src/spice-session.c b/src/spice-session.c
index db40a53..2135348 100644
--- a/src/spice-session.c
+++ b/src/spice-session.c
@@ -123,6 +123,8 @@ struct _SpiceSessionPrivate {
  gchar *name;
  SpiceImageCompression preferred_compression;
  
+bool  gst_init_by_spice;

+
  /* associated objects */
  SpiceAudio*audio_manager;
  SpiceUsbDeviceManager *usb_manager;
@@ -343,6 +345,10 @@ spice_session_dispose(GObject *gobject)
  g_warn_if_fail(s->channels_destroying == 0);
  g_warn_if_fail(s->channels == NULL);
  
+if (session->priv->gst_init_by_spice) {

+gst_deinit();



Wouldn't it deinit on migration? (IIRC a new session is created)


Actually gstreamer documentation states:

"It is normally not needed to call this function in a normal application
 as the resources will automatically be freed when the program terminates.
 This function is therefore mostly used by testsuites and other memory
 profiling tools."

Before it was used only by spicy which i guess it's considered more of a 
test
client, I'm not sure we would like to deinit by the session (on the 
other hand

i'm also not sure how harmful it would be)


Snir.



+}
+
  g_clear_object(&s->audio_manager);
  g_clear_object(&s->usb_manager);
  g_clear_object(&s->proxy);
@@ -2888,5 +2894,7 @@ spice_session_enable_gstreamer(SpiceSession *session)
  if (!gst_init_check(NULL, NULL, &err)) {
  spice_warning("Disabling GStreamer video support: %s", err->message);
  g_clear_error(&err);
+} else {
+session->priv->gst_init_by_spice = true;
  }
  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [spice-gtk v1 2/6] display-gst: rely on SpiceSession init of GStreamer

2019-09-08 Thread Snir Sheriber

Hi,


On 9/2/19 7:04 PM, Victor Toso wrote:

From: Victor Toso 

This means we can drop gstvideo_init() function and replace its calls
with gst_is_initialized().

Signed-off-by: Victor Toso 
---
  src/channel-display-gst.c | 23 +--
  1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 6fccf62..a34b5d0 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -748,22 +748,6 @@ static gboolean spice_gst_decoder_queue_frame(VideoDecoder 
*video_decoder,
  return TRUE;
  }
  
-static gboolean gstvideo_init(void)

-{
-static int success = 0;
-if (!success) {
-GError *err = NULL;
-if (gst_init_check(NULL, NULL, &err)) {
-success = 1;
-} else {
-spice_warning("Disabling GStreamer video support: %s", 
err->message);
-g_clear_error(&err);
-success = -1;
-}
-}
-return success > 0;
-}
-
  G_GNUC_INTERNAL
  VideoDecoder* create_gstreamer_decoder(int codec_type, display_stream *stream)
  {
@@ -771,7 +755,7 @@ VideoDecoder* create_gstreamer_decoder(int codec_type, 
display_stream *stream)
  
  g_return_val_if_fail(VALID_VIDEO_CODEC_TYPE(codec_type), NULL);
  
-if (gstvideo_init()) {

+if (gst_is_initialized()) {


Since the logical thing to do is usually to initialize gstreamer
once you start using it i would add a comment it's now initialized
by the session (if not externally)

(also on gstaudio)

Snir.


  decoder = g_new0(SpiceGstDecoder, 1);
  decoder->base.destroy = spice_gst_decoder_destroy;
  decoder->base.reschedule = spice_gst_decoder_reschedule;
@@ -820,7 +804,10 @@ gboolean gstvideo_has_codec(int codec_type)
  GstCaps *caps;
  GstElementFactoryListType type;
  
-g_return_val_if_fail(gstvideo_init(), FALSE);

+if (!gst_is_initialized()) {
+return FALSE;
+}
+
  g_return_val_if_fail(VALID_VIDEO_CODEC_TYPE(codec_type), FALSE);
  
  type = GST_ELEMENT_FACTORY_TYPE_DECODER |

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk v3] streaming: make draw-area visible on MJPEG encoder creation

2019-09-02 Thread Snir Sheriber

Hi,

On 9/2/19 6:50 PM, Kevin Pouget wrote:

This patch allows the MJPEG encoder to inform the spice-widget that
its video drawing area (draw-area) should be made visible on screen.

This is required to switch from GST video decoding to native MJPEG
decoding, otherwise the gst-area remained on top and the MJPEG video
stream was never shown.

Signed-off-by: Kevin Pouget 
---
v2 -> v3: address Snir comments:

- comment about NULL in the signal description
- move 'if (pipeline_ptr == NULL) ...' outside  of 'if 
defined(GDK_WINDOWING_X11)'

regarding EGL note, it might be something like this:


gtk_stack_set_visible_child_name(d->stack, egl_enabled(d) ?
"gl-area" : "draw-area");



Yes, but AFAIU this should never happen

So I'll ack also without it.

Snir.


but it's just a wild guess!

---
  src/channel-display-mjpeg.c |  3 +++
  src/channel-display.c   |  4 +++-
  src/spice-widget.c  | 11 +--
  3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
index 647d31b..636a98b 100644
--- a/src/channel-display-mjpeg.c
+++ b/src/channel-display-mjpeg.c
@@ -300,5 +300,8 @@ VideoDecoder* create_mjpeg_decoder(int codec_type, 
display_stream *stream)

  /* All the other fields are initialized to zero by g_new0(). */

+/* makes the draw-area visible */
+hand_pipeline_to_widget(stream, NULL);
+
  return (VideoDecoder*)decoder;
  }
diff --git a/src/channel-display.c b/src/channel-display.c
index 59c809d..cd87c7c 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -485,7 +485,9 @@ static void 
spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
   *
   * The #SpiceDisplayChannel::gst-video-overlay signal is emitted when
   * pipeline is ready and can be passed to widget to register GStreamer
- * overlay interface and other GStreamer callbacks.
+ * overlay interface and other GStreamer callbacks. If the pipeline
+ * pointer is NULL, the drawing area of the native renderer is set
+ * visible.
   *
   * Returns: %TRUE if the overlay is being set
   *
diff --git a/src/spice-widget.c b/src/spice-widget.c
index a9ba1f1..d73e02f 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -2780,14 +2780,20 @@ static void gst_size_allocate(GtkWidget *widget, 
GdkRectangle *a, gpointer data)
  }

  /* This callback should pass to the widget a pointer of the pipeline
- * so that we can set pipeline and overlay related calls from here.
+ * so that we can the set GST pipeline and overlay related calls from
+ * here.  If the pipeline pointer is NULL, the drawing area of the
+ * native renderer is set visible.
   */
  static gboolean set_overlay(SpiceChannel *channel, void* pipeline_ptr, 
SpiceDisplay *display)
  {
-#if defined(GDK_WINDOWING_X11)
  SpiceDisplayPrivate *d = display->priv;

+if (pipeline_ptr == NULLg0) {
+gtk_stack_set_visible_child_name(d->stack, "draw-area");
+return true;
+}
+
+#if defined(GDK_WINDOWING_X11)
  /* GstVideoOverlay is currently used only under x */
  if (!g_getenv("DISABLE_GSTVIDEOOVERLAY") &&
  GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
--
2.21.0
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH] streaming: make draw-area visible on MJPEG encoder creation

2019-09-02 Thread Snir Sheriber

Hi,

On 8/29/19 7:17 PM, Frediano Ziglio wrote:

This patch allows the MJPEG encoder to inform the spice-widget that
its video drawing area (draw-area) should be made visible on screen.

This is required to switch from GST video decoding to native MJPEG
decoding, otherwise the gst-area remained on top and the MJPEG video
stream was never shown.

Signed-off-by: Kevin Pouget 

Fine for me. Snir had the most comments on earlier versions.


---
  src/channel-display-mjpeg.c | 3 +++
  src/spice-widget.c  | 9 -
  2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
index 647d31b..636a98b 100644
--- a/src/channel-display-mjpeg.c
+++ b/src/channel-display-mjpeg.c
@@ -300,5 +300,8 @@ VideoDecoder* create_mjpeg_decoder(int codec_type,
display_stream *stream)
  
  /* All the other fields are initialized to zero by g_new0(). */
  
+/* makes the draw-area visible */

+hand_pipeline_to_widget(stream, NULL);
+
  return (VideoDecoder*)decoder;
  }
diff --git a/src/spice-widget.c b/src/spice-widget.c
index a9ba1f1..7c257ff 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -2780,13 +2780,20 @@ static void gst_size_allocate(GtkWidget *widget,
GdkRectangle *a, gpointer data)
  }
  
  /* This callback should pass to the widget a pointer of the pipeline

- * so that we can set pipeline and overlay related calls from here.
+ * so that we can the set GST pipeline and overlay related calls from
+ * here.  If the pipeline pointer is NULL, the drawing area of the
+ * native renderer is set visible.
   */


I think you should update also the signal comment (gst-video-overlay), that
the pipeline may be NULL


  static gboolean set_overlay(SpiceChannel *channel, void* pipeline_ptr,
  SpiceDisplay *display)
  {
  #if defined(GDK_WINDOWING_X11)
  SpiceDisplayPrivate *d = display->priv;
  
+if (pipeline_ptr == NULL) {

+gtk_stack_set_visible_child_name(d->stack, "draw-area");
+return true;
+}
+


Although this would probably always work fine and returned value is
also not checked but the draw-area is not necessarily related to X11
so it should be outside the define.

Consider these, but other than that fine with me

(Oh, another not really necessary thing would be to make sure egl is not
enabled, but probably should never happen :p)

Snir.



  /* GstVideoOverlay is currently used only under x */
  if (!g_getenv("DISABLE_GSTVIDEOOVERLAY") &&
  GDK_IS_X11_DISPLAY(gdk_display_get_default())) {

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-gtk] meson: Bump minimum required meson_version to 0.50

2019-08-28 Thread Snir Sheriber
This will drop the following warning:
"Project specifies a minimum meson_version '>= 0.49' but uses
 features which were added in newer versions"

Signed-off-by: Snir Sheriber 
---
 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 07dbb70..eeae356 100644
--- a/meson.build
+++ b/meson.build
@@ -4,7 +4,7 @@
 project('spice-gtk', 'c',
  version : run_command('build-aux/git-version-gen', 
'@0@/.tarball-version'.format(meson.source_root()), check : 
true).stdout().strip(),
  license : 'LGPLv2.1',
- meson_version : '>= 0.49')
+ meson_version : '>= 0.50')
 
 meson.add_dist_script('build-aux/meson-dist', meson.project_version(), 
meson.source_root())
 
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk 2/2] Add copr builds integration

2019-08-28 Thread Snir Sheriber

Hi,

On 8/28/19 1:36 PM, Frediano Ziglio wrote:

Hi,

On 8/27/19 10:49 PM, Marc-André Lureau wrote:

Hi

On Tue, Aug 27, 2019 at 6:27 PM Snir Sheriber  wrote:

This will let copr to generate srpm using the .copr/Makefile script

Do we really want to maintain that kind of distro things upstream? Do
we need it?

What does it bring that gitlab CI doesn't have?


This srpm is generated with every commit and then a build is triggered
in copr so that we'll have a repository of latest upstream packages which
can be easily enabled by simple "dnf copr enable X" command.
This should eventually replace the nightly builds repo which is currently
created by an unmaintained vm that runs cron job that creates the srpms
and push to copr (there is also a git repo for the spec file templates used
by it).

IMO replacing the current nightly copr should be more a requirement than a
"should". Removing an hidden, not open VM into some small hooks configuration
with open source code that people can change sounds really nice thing.
Having two semi-official development setups to package/use SPICE seems a
bit too much.


Hence the intention was not to use it as ci, just for creating this repo, if
i could have easily push the srpm created by gitlab ci to copr i would have
done it. (can be done but would require to maintain our own runners)


Mumble... could we not use artifacts and a webhook? So CI prepare the SRPM,
save in the artifacts and send a link to the SRPM using a copr webhook
(or something similar, not sure what can be done in copr)



AFAIK you cannot pass a link to copr.

BUT if it's a known address we may be able to do one of the following:

1. Create the SRPM in gitlab and use a small script to just to download 
it to

    copr's srpm_output dir.

2. Pass only the tarball as artifact and have a small script to download 
it and

    create the SRPM in the srpm_output dir of copr

Then copr will take the srpm from this dir and execute a build

This way we even can drop the Makefile since it's also possible to have the
script directly in copr (without root privileges)

I'll test those options, thanks!





Signed-off-by: Snir Sheriber 
---
   .copr/Makefile | 29 +
   1 file changed, 29 insertions(+)
   create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..db297fb
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,29 @@
+# This Makefile script is invoked by copr to build source rpm
+# See:
https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm

When is the build actually triggered? Is copr monitoring the git
repository? Is there a hook somewhere in gitlab to trigger the build?


Yes, there is a gitlab hook that should be enabled (just by adding
the copr webhook url as gitlab hook)


Do you mean a gitlab (as gitlab.freedesktop.org) hook that trigger copr
build?



Yes

Snir.



+
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = meson gcc xz git rpm-build
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol && meson -Dprefix=/usr/ build && ninja -C build
install
+   rm -rf spice-protocol
+
+   # get other dependencies for project excluding spice-protocol
+   dnf install -y `sed '/^BuildRequires:/!d; s/.*://;
s/\bspice-protocol\b//; s/>.*//' *.spec.in`
+
+   # do not use commit id for version
+   git fetch --tags
+   git describe --abbrev=0 | sed 's/v//' > .tarball-version
+   # create source rpm
+   meson --buildtype=release build
+   # Meson does not update submodules recursively
+   git submodule update --init --recursive
+   # this fix an issue with Meson dist
+   if ! test -r ../spice-common.git; then DIR=`basename "$$PWD"`; ln
-s "$$DIR/.git/modules/spice-common" ../spice-common.git; fi
+   rm -rf meson-dist
+   ninja -C build dist
+   rpmbuild -bs ./build/*spec --define "_sourcedir
$$PWD/build/meson-dist/" --define "_srcrpmdir $(outdir)"

Too much hacks for my taste here.


I agree but it's still less hacks than what we have now in order to
create the
nightly repo, hopefully this will become simpler once some copr & meson
issues will be solved (or we'll be able to use rpkg when it will support
submodules)

Snir.


Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk 2/2] Add copr builds integration

2019-08-28 Thread Snir Sheriber

Hi,

On 8/27/19 10:49 PM, Marc-André Lureau wrote:

Hi

On Tue, Aug 27, 2019 at 6:27 PM Snir Sheriber  wrote:

This will let copr to generate srpm using the .copr/Makefile script

Do we really want to maintain that kind of distro things upstream? Do
we need it?

What does it bring that gitlab CI doesn't have?



This srpm is generated with every commit and then a build is triggered
in copr so that we'll have a repository of latest upstream packages which
can be easily enabled by simple "dnf copr enable X" command.
This should eventually replace the nightly builds repo which is currently
created by an unmaintained vm that runs cron job that creates the srpms
and push to copr (there is also a git repo for the spec file templates used
by it).

Hence the intention was not to use it as ci, just for creating this repo, if
i could have easily push the srpm created by gitlab ci to copr i would have
done it. (can be done but would require to maintain our own runners)




Signed-off-by: Snir Sheriber 
---
  .copr/Makefile | 29 +
  1 file changed, 29 insertions(+)
  create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..db297fb
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,29 @@
+# This Makefile script is invoked by copr to build source rpm
+# See: https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm

When is the build actually triggered? Is copr monitoring the git
repository? Is there a hook somewhere in gitlab to trigger the build?



Yes, there is a gitlab hook that should be enabled (just by adding
the copr webhook url as gitlab hook)





+
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = meson gcc xz git rpm-build
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol && meson -Dprefix=/usr/ build && ninja -C build 
install
+   rm -rf spice-protocol
+
+   # get other dependencies for project excluding spice-protocol
+   dnf install -y `sed '/^BuildRequires:/!d; s/.*://; s/\bspice-protocol\b//; 
s/>.*//' *.spec.in`
+
+   # do not use commit id for version
+   git fetch --tags
+   git describe --abbrev=0 | sed 's/v//' > .tarball-version
+   # create source rpm
+   meson --buildtype=release build
+   # Meson does not update submodules recursively
+   git submodule update --init --recursive
+   # this fix an issue with Meson dist
+   if ! test -r ../spice-common.git; then DIR=`basename "$$PWD"`; ln -s 
"$$DIR/.git/modules/spice-common" ../spice-common.git; fi
+   rm -rf meson-dist
+   ninja -C build dist
+   rpmbuild -bs ./build/*spec --define "_sourcedir $$PWD/build/meson-dist/" --define 
"_srcrpmdir $(outdir)"

Too much hacks for my taste here.



I agree but it's still less hacks than what we have now in order to 
create the

nightly repo, hopefully this will become simpler once some copr & meson
issues will be solved (or we'll be able to use rpkg when it will support
submodules)

Snir.





--
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel




___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk 1/2] Add spec.in file and spec file generation

2019-08-28 Thread Snir Sheriber

Hi,

On 8/27/19 5:50 PM, Frediano Ziglio wrote:

I posted a similar patch for another SPICE project, fine adding SPEC to the
repository.



Yes just found it, for spice-protocol (autotools)



The spec seems already "evolved" from a past history. Where did you get it
from? I think that comment should be on the commit message.
Also, is that spec file supposed to be used for releases (like for Fedora) ?



It's mainly based on latest fedora build spec with few minor changes,
my intention was to use it as a spec template, upstream build can
use it with a couple of changes.

On the other hand if it's preferred to be the official upstream spec i can
add the changelog and move necessary copr changes to the Makefile
script.





Signed-off-by: Snir Sheriber 
---
Test build:
https://copr.fedorainfracloud.org/coprs/snir/spice-project/build/1021943/

---
  meson.build   |  11 +++
  spice-gtk.spec.in | 190 ++
  2 files changed, 201 insertions(+)
  create mode 100644 spice-gtk.spec.in

diff --git a/meson.build b/meson.build
index 07dbb70..61f8a11 100644
--- a/meson.build
+++ b/meson.build
@@ -408,3 +408,14 @@ if spice_gtk_has_gtk
   requires : 'spice-client-glib-2.0 gtk+-3.0 >=
   @0@'.format(gtk_version_required),
   variables : 'exec_prefix=${prefix}')
  endif
+
+#
+# spec file
+#
+conf_data = configuration_data()
+conf_data.set('version', meson.project_version())
+conf_data.set('release', run_command('date', '+%Y%m%d%H%M.spice.latest',
check : true).stdout().strip())

Not big fun of this, I suppose this means that these build are only for
developers.



Yes, possibly can be changed only in the Makefile script.


Snir.




+
+configure_file(input : 'spice-gtk.spec.in',
+   output : 'spice-gtk.spec',
+   configuration : conf_data)
diff --git a/spice-gtk.spec.in b/spice-gtk.spec.in
new file mode 100644
index 000..b4c1051
--- /dev/null
+++ b/spice-gtk.spec.in
@@ -0,0 +1,190 @@
+#define _version_suffix
+
+Name:   spice-gtk
+Version:@version@
+Release:@release@%{?dist}
+Summary:A GTK+ widget for SPICE clients
+
+License:LGPLv2+
+URL:https://www.spice-space.org/
+#VCS:   git:git://anongit.freedesktop.org/spice/spice-gtk
+Source0:
https://www.spice-space.org/download/gtk/%{name}-%{version}%{?_version_suffix}.tar.xz
+
+BuildRequires: git-core
+BuildRequires: meson
+BuildRequires: intltool
+BuildRequires: usbredir-devel >= 0.7.1
+BuildRequires: libusb1-devel >= 1.0.16
+BuildRequires: pixman-devel libjpeg-turbo-devel
+BuildRequires: opus-devel
+BuildRequires: zlib-devel
+BuildRequires: cyrus-sasl-devel
+BuildRequires: libcacard-devel
+BuildRequires: gobject-introspection-devel
+BuildRequires: libacl-devel
+%if ! 0%{?flatpak}
+BuildRequires: polkit-devel
+%endif
+BuildRequires: gtk-doc
+BuildRequires: vala
+BuildRequires: usbutils
+BuildRequires: libsoup-devel >= 2.49.91
+BuildRequires: libphodav-devel
+BuildRequires: lz4-devel
+BuildRequires: gtk3-devel
+BuildRequires: json-glib-devel
+BuildRequires: spice-protocol >= 0.12.15
+BuildRequires: gstreamer1-devel >= 1.10
+BuildRequires: gstreamer1-plugins-base-devel >= 1.10
+BuildRequires: python3-six
+BuildRequires: python3-pyparsing
+BuildRequires: openssl-devel
+BuildRequires: gnupg2
+
+Obsoletes: spice-gtk-python < 0.32
+
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description
+Client libraries for SPICE desktop servers.
+
+%package -n spice-glib
+Summary: A GObject for communicating with Spice servers
+
+%description -n spice-glib
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+%package -n spice-glib-devel
+Summary: Development files to build Glib2 applications with spice-glib-2.0
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: glib2-devel
+
+%description -n spice-glib-devel
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+Libraries, includes, etc. to compile with the spice-glib-2.0 libraries
+
+%package -n spice-gtk3
+Summary: A GTK3 widget for SPICE clients
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description -n spice-gtk3
+spice-client-glib-3.0 is a SPICE client library for Gtk3.
+
+%package -n spice-gtk3-devel
+Summary: Development files to build GTK3 applications with spice-gtk-3.0
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+Requires: spice-glib-devel%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: gtk3-devel
+Obsoletes: spice-gtk-devel < 0.32
+
+%description -n spice-gtk3-devel
+spice-client-gtk-3.0 provides a SPICE viewer widget for GTK3.
+
+Libraries, includes, etc. to compile with the spice-gtk3 libraries
+
+%package -n spice-gtk3-vala
+Summary: Vala bindings for the spice-gtk-3.0 library
+Requires: spice-gtk3%{?_isa} =

[Spice-devel] [PATCH spice-gtk 2/2] Add copr builds integration

2019-08-27 Thread Snir Sheriber
This will let copr to generate srpm using the .copr/Makefile script

Signed-off-by: Snir Sheriber 
---
 .copr/Makefile | 29 +
 1 file changed, 29 insertions(+)
 create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..db297fb
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,29 @@
+# This Makefile script is invoked by copr to build source rpm
+# See: https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm
+
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = meson gcc xz git rpm-build
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol && meson -Dprefix=/usr/ build && ninja -C build 
install
+   rm -rf spice-protocol
+
+   # get other dependencies for project excluding spice-protocol
+   dnf install -y `sed '/^BuildRequires:/!d; s/.*://; 
s/\bspice-protocol\b//; s/>.*//' *.spec.in`
+
+   # do not use commit id for version
+   git fetch --tags
+   git describe --abbrev=0 | sed 's/v//' > .tarball-version
+   # create source rpm
+   meson --buildtype=release build
+   # Meson does not update submodules recursively
+   git submodule update --init --recursive
+   # this fix an issue with Meson dist
+   if ! test -r ../spice-common.git; then DIR=`basename "$$PWD"`; ln -s 
"$$DIR/.git/modules/spice-common" ../spice-common.git; fi
+   rm -rf meson-dist
+   ninja -C build dist
+   rpmbuild -bs ./build/*spec --define "_sourcedir 
$$PWD/build/meson-dist/" --define "_srcrpmdir $(outdir)"
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-gtk 1/2] Add spec.in file and spec file generation

2019-08-27 Thread Snir Sheriber
Signed-off-by: Snir Sheriber 
---
Test build:
https://copr.fedorainfracloud.org/coprs/snir/spice-project/build/1021943/

---
 meson.build   |  11 +++
 spice-gtk.spec.in | 190 ++
 2 files changed, 201 insertions(+)
 create mode 100644 spice-gtk.spec.in

diff --git a/meson.build b/meson.build
index 07dbb70..61f8a11 100644
--- a/meson.build
+++ b/meson.build
@@ -408,3 +408,14 @@ if spice_gtk_has_gtk
  requires : 'spice-client-glib-2.0 gtk+-3.0 >= 
@0@'.format(gtk_version_required),
  variables : 'exec_prefix=${prefix}')
 endif
+
+#
+# spec file
+#
+conf_data = configuration_data()
+conf_data.set('version', meson.project_version())
+conf_data.set('release', run_command('date', '+%Y%m%d%H%M.spice.latest', check 
: true).stdout().strip())
+
+configure_file(input : 'spice-gtk.spec.in',
+   output : 'spice-gtk.spec',
+   configuration : conf_data)
diff --git a/spice-gtk.spec.in b/spice-gtk.spec.in
new file mode 100644
index 000..b4c1051
--- /dev/null
+++ b/spice-gtk.spec.in
@@ -0,0 +1,190 @@
+#define _version_suffix
+
+Name:   spice-gtk
+Version:@version@
+Release:@release@%{?dist}
+Summary:A GTK+ widget for SPICE clients
+
+License:LGPLv2+
+URL:https://www.spice-space.org/
+#VCS:   git:git://anongit.freedesktop.org/spice/spice-gtk
+Source0:
https://www.spice-space.org/download/gtk/%{name}-%{version}%{?_version_suffix}.tar.xz
+
+BuildRequires: git-core
+BuildRequires: meson
+BuildRequires: intltool
+BuildRequires: usbredir-devel >= 0.7.1
+BuildRequires: libusb1-devel >= 1.0.16
+BuildRequires: pixman-devel libjpeg-turbo-devel
+BuildRequires: opus-devel
+BuildRequires: zlib-devel
+BuildRequires: cyrus-sasl-devel
+BuildRequires: libcacard-devel
+BuildRequires: gobject-introspection-devel
+BuildRequires: libacl-devel
+%if ! 0%{?flatpak}
+BuildRequires: polkit-devel
+%endif
+BuildRequires: gtk-doc
+BuildRequires: vala
+BuildRequires: usbutils
+BuildRequires: libsoup-devel >= 2.49.91
+BuildRequires: libphodav-devel
+BuildRequires: lz4-devel
+BuildRequires: gtk3-devel
+BuildRequires: json-glib-devel
+BuildRequires: spice-protocol >= 0.12.15
+BuildRequires: gstreamer1-devel >= 1.10
+BuildRequires: gstreamer1-plugins-base-devel >= 1.10
+BuildRequires: python3-six
+BuildRequires: python3-pyparsing
+BuildRequires: openssl-devel
+BuildRequires: gnupg2
+
+Obsoletes: spice-gtk-python < 0.32
+
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description
+Client libraries for SPICE desktop servers.
+
+%package -n spice-glib
+Summary: A GObject for communicating with Spice servers
+
+%description -n spice-glib
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+%package -n spice-glib-devel
+Summary: Development files to build Glib2 applications with spice-glib-2.0
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: glib2-devel
+
+%description -n spice-glib-devel
+spice-client-glib-2.0 is a SPICE client library for GLib2.
+
+Libraries, includes, etc. to compile with the spice-glib-2.0 libraries
+
+%package -n spice-gtk3
+Summary: A GTK3 widget for SPICE clients
+Requires: spice-glib%{?_isa} = %{version}-%{release}
+
+%description -n spice-gtk3
+spice-client-glib-3.0 is a SPICE client library for Gtk3.
+
+%package -n spice-gtk3-devel
+Summary: Development files to build GTK3 applications with spice-gtk-3.0
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+Requires: spice-glib-devel%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Requires: gtk3-devel
+Obsoletes: spice-gtk-devel < 0.32
+
+%description -n spice-gtk3-devel
+spice-client-gtk-3.0 provides a SPICE viewer widget for GTK3.
+
+Libraries, includes, etc. to compile with the spice-gtk3 libraries
+
+%package -n spice-gtk3-vala
+Summary: Vala bindings for the spice-gtk-3.0 library
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+Requires: spice-gtk3-devel%{?_isa} = %{version}-%{release}
+
+%description -n spice-gtk3-vala
+A module allowing use of the spice-gtk-3.0 widget from vala
+
+%package tools
+Summary: Spice-gtk tools
+Requires: spice-gtk3%{?_isa} = %{version}-%{release}
+
+%description tools
+Simple clients for interacting with SPICE servers.
+spicy is a client to a SPICE desktop server.
+spicy-screenshot is a tool to capture screen-shots of a SPICE desktop.
+
+
+%prep
+%autosetup -S git_am
+
+
+%build
+
+# meson macro has --auto-features=enabled
+# gstreamer should be enough, may be deprecated in the future
+%global mjpegflag -Dbuiltin-mjpeg=false
+# spice-common doesn't use auto feature yet
+%global celt051flag -Dcelt051=disabled
+# pulse is deprecated upstream
+%global pulseflag -Dpulse=disabled
+
+%meson \
+  %{mjpegflag} \
+  %{celt051flag} \
+  %{pulseflag} \
+%if 0%{?flatpak}
+  -Dpolkit=disabled
+%

[Spice-devel] [RFC spice-streaming-agent 3/3] gst-plugin: Use Xlib capture helper

2019-08-26 Thread Snir Sheriber
---
 src/Makefile.am|  2 ++
 src/gst-plugin.cpp | 43 +++
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 31b8af1..1de8f9a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -98,6 +98,8 @@ gst_plugin_la_LIBADD = \
 
 gst_plugin_la_SOURCES = \
gst-plugin.cpp \
+   xlib-capture.cpp \
+   xlib-capture.hpp \
$(NULL)
 
 gst_plugin_la_CPPFLAGS = \
diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 70bc6c8..83a54d5 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -17,6 +17,7 @@
 #define XLIB_CAPTURE 1
 #if XLIB_CAPTURE
 #include 
+#include "xlib-capture.hpp"
 #endif
 
 #include 
@@ -71,6 +72,7 @@ private:
 Display *const dpy;
 #if XLIB_CAPTURE
 void xlib_capture();
+XlibCapture *xc;
 #endif
 GstElementUPtr pipeline, capture, sink;
 GstSampleUPtr sample;
@@ -281,6 +283,7 @@ GstreamerFrameCapture::GstreamerFrameCapture(const 
GstreamerEncoderSettings &set
 if (!dpy) {
 throw std::runtime_error("Unable to initialize X11");
 }
+xc = new XlibCapture(dpy);
 pipeline_init(settings);
 }
 
@@ -296,6 +299,7 @@ GstreamerFrameCapture::~GstreamerFrameCapture()
 {
 free_sample();
 gst_element_set_state(pipeline.get(), GST_STATE_NULL);
+delete xc;
 XCloseDisplay(dpy);
 }
 
@@ -305,27 +309,23 @@ void GstreamerFrameCapture::Reset()
 }
 
 #if XLIB_CAPTURE
-void free_ximage(gpointer data)
+void free_ximg(gpointer data)
 {
-XImage *image = (XImage*)data;
-image->f.destroy_image(image);
+delete (XImg *) data;
 }
 
 void GstreamerFrameCapture::xlib_capture()
 {
-int screen = XDefaultScreen(dpy);
 
-Window win = RootWindow(dpy, screen);
-XWindowAttributes win_info;
-XGetWindowAttributes(dpy, win, &win_info);
+XImg *image = xc->capture();
+if (!image) {
+throw std::runtime_error("Cannot capture from X");
+}
 
 /* Some encoders cannot handle odd resolution make sure it's even number 
of pixels */
-cur_width = win_info.width - win_info.width % 2;
-cur_height =  win_info.height - win_info.height % 2;
-
-if (cur_width != last_width || cur_height != last_height) {
-last_width = cur_width;
-last_height = cur_height;
+if (image->new_resolution()) {
+last_width = cur_width = image->width(); // TODO: drop?
+last_height = cur_height = image->height();
 is_first = true;
 
 gst_app_src_end_of_stream(GST_APP_SRC(capture.get()));
@@ -333,24 +333,19 @@ void GstreamerFrameCapture::xlib_capture()
 gst_element_set_state(pipeline.get(), GST_STATE_PLAYING);
 }
 
-XImage *image = XGetImage(dpy, win, 0, 0,
-  cur_width, cur_height, AllPlanes, ZPixmap);
-if (!image) {
-throw std::runtime_error("Cannot capture from X");
-}
+GstBufferUPtr 
buf(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, 
image->get_data(),
+  image->data_size(), 0,
+  image->data_size(), image,
+  free_ximg));
 
-GstBufferUPtr 
buf(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, 
image->data,
-  image->height * 
image->bytes_per_line, 0,
-  image->height * 
image->bytes_per_line, image,
-  free_ximage));
 if (!buf) {
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
 GstCapsUPtr caps(gst_caps_new_simple("video/x-raw",
  "format", G_TYPE_STRING, "BGRx",
- "width", G_TYPE_INT, image->width,
- "height", G_TYPE_INT, image->height,
+ "width", G_TYPE_INT, image->width(),
+ "height", G_TYPE_INT, image->height(),
  "framerate", GST_TYPE_FRACTION, 
settings.fps, 1,
  nullptr));
 
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [RFC spice-streaming-agent 1/3] Add Xlib capture helper files

2019-08-26 Thread Snir Sheriber
The Xlib capture helper provides a wrapping class for XImage, Display
information and other capturing related functionalities which allows
to use unified and simple API for screen capturing using X.
This also utilize the X MIT-SHM extension which improves capturing
speed, hence, xext is required.
---

The original idea was just to use the X ancient MIT-SHM extension which
reduce CPU utilization significantly when using Xlib capturing.
Since this capturing method is currently used by two different plugins
it was suggested to use one common class for that, this class is added
by this patch and the 2 following patches makes the existing plugins
to use this class.

If you have any other suggestions or comments please do ;)

---
 configure.ac |   1 +
 src/xlib-capture.cpp | 169 +++
 src/xlib-capture.hpp |  53 ++
 3 files changed, 223 insertions(+)
 create mode 100644 src/xlib-capture.cpp
 create mode 100644 src/xlib-capture.hpp

diff --git a/configure.ac b/configure.ac
index 1c7788b..3220e27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,7 @@ PKG_CHECK_MODULES(DRM, libdrm)
 PKG_CHECK_MODULES(X11, x11)
 PKG_CHECK_MODULES(XFIXES, xfixes)
 PKG_CHECK_MODULES(XRANDR, xrandr)
+PKG_CHECK_MODULES(XEXT, xext)
 
 PKG_CHECK_MODULES(JPEG, libjpeg, , [
 AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
diff --git a/src/xlib-capture.cpp b/src/xlib-capture.cpp
new file mode 100644
index 000..7837ee2
--- /dev/null
+++ b/src/xlib-capture.cpp
@@ -0,0 +1,169 @@
+/* A helper classes that wraps X display information XImage capturing functions
+ *
+ * \copyright
+ * Copyright 2019 Red Hat Inc. All rights reserved.
+ */
+
+#include 
+#include 
+#include "xlib-capture.hpp"
+
+namespace spice {
+namespace streaming_agent {
+
+/ XImg Class Impl ***/
+
+XImg::XImg(XImage *x_image, bool is_shm, bool new_res) {
+ this->x_image = x_image;
+ this->x_shm = is_shm;
+ this->new_res = new_res;
+}
+
+XImg::~XImg() {
+if (!x_shm) {
+XDestroyImage(x_image);
+} // else the XlibCapture will destroy it
+}
+
+char *XImg::get_data() {
+return x_image->data;
+}
+
+int XImg::height() {
+return x_image->height;
+}
+
+int XImg::width() {
+return x_image->width;
+}
+
+int XImg::data_size() {
+return x_image->height * x_image->bytes_per_line;
+}
+
+bool XImg::new_resolution() {
+   return new_res;
+}
+
+/** XlibCapture Class Impl ***/
+
+static int (*previous_x_err_handler)(Display *display, XErrorEvent *event) = 0;
+static bool xerror = false;
+
+/* This is used mainly to silence x error in case of resolution change */
+static int x_err_handler(Display *display, XErrorEvent *event) {
+//TODO: print some error information ?
+switch (event->error_code) {
+case BadAccess:
+case BadMatch:
+xerror = true;
+return 0;
+default:
+return previous_x_err_handler(display, event);
+}
+}
+
+void XlibCapture::init_xshm() {
+Visual *visual = DefaultVisual(display, screen);
+unsigned int depth = DefaultDepth(display, screen);
+XWindowAttributes win_info;
+
+xshm_enabled = false;
+xerror = false;
+// Create Shared Memory XImage
+XGetWindowAttributes(display, win, &win_info); // update attributes
+xshm_image = XShmCreateImage(display, visual, depth, ZPixmap, nullptr,
+ &shm_info, win_info.width, win_info.height);
+if (!xshm_image) {
+return;
+}
+// Allocate shm buffer
+int shm_id = shmget(IPC_PRIVATE, xshm_image->bytes_per_line * 
xshm_image->height, IPC_CREAT|0777);
+if (shm_id == -1) {
+XDestroyImage(xshm_image);
+return;
+}
+
+// Attach share memory bufer
+void *shm_addr = shmat(shm_id, nullptr, 0);
+if (shm_addr == (void*)-1) {
+XDestroyImage(xshm_image);
+shmctl(shm_id, IPC_RMID, nullptr);
+return;
+}
+shm_info.shmid = shm_id;
+shm_info.shmaddr = xshm_image->data = (char*)shm_addr;
+shm_info.readOnly = false;
+XShmAttach(display, &shm_info);
+XSync(display, false);
+
+if (!xerror) {
+xshm_enabled = true;
+return; // XShm initialization succeeded
+}
+}
+
+XImg *XlibCapture::capture() {
+XWindowAttributes win_info;
+bool changed = false;
+int tries = 0;
+
+/* This code flow allows to overcome resolution change that occurs just
+ * after getting the attributes and before asking for the XImage
+ */
+do {
+XGetWindowAttributes(display, win, &win_info); // update attributes
+
+if (last_width != win_info.width || last_height != win_info.height) {
+if (xshm_enabled && xshm_image) { // reinit xshm extention
+deinit_xshm();
+init_xshm();
+}
+changed = true; // resolution changed
+last_width = win_info.width;
+  

[Spice-devel] [RFC spice-streaminh-agent 2/3] mjpeg-fallback: Use Xlib capture helper

2019-08-26 Thread Snir Sheriber
---
 src/Makefile.am|  4 
 src/mjpeg-fallback.cpp | 38 +-
 2 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 0133bf5..31b8af1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,7 @@ AM_CPPFLAGS = \
$(X11_CFLAGS) \
$(XFIXES_CFLAGS) \
$(XRANDR_CFLAGS) \
+   $(XEXT_CFLAGS) \
$(NULL)
 
 AM_CFLAGS = \
@@ -56,6 +57,7 @@ spice_streaming_agent_LDADD = \
$(X11_LIBS) \
$(XFIXES_LIBS) \
$(XRANDR_LIBS) \
+   $(XEXT_LIBS) \
$(JPEG_LIBS) \
$(NULL)
 
@@ -77,6 +79,8 @@ spice_streaming_agent_SOURCES = \
utils.cpp \
utils.hpp \
x11-display-info.cpp \
+   xlib-capture.cpp \
+   xlib-capture.hpp \
$(NULL)
 
 if HAVE_GST
diff --git a/src/mjpeg-fallback.cpp b/src/mjpeg-fallback.cpp
index 03247a1..a43825b 100644
--- a/src/mjpeg-fallback.cpp
+++ b/src/mjpeg-fallback.cpp
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include "xlib-capture.hpp"
 
 using namespace spice::streaming_agent;
 
@@ -44,11 +45,10 @@ public:
 private:
 MjpegSettings settings;
 Display *const dpy;
+XlibCapture *xc;
 
 std::vector frame;
 
-// last frame sizes
-int last_width = -1, last_height = -1;
 // last time before capture
 uint64_t last_time = 0;
 };
@@ -58,19 +58,21 @@ private:
 MjpegFrameCapture::MjpegFrameCapture(const MjpegSettings& settings):
 settings(settings),dpy(XOpenDisplay(nullptr))
 {
-if (!dpy)
+if (!dpy) {
 throw std::runtime_error("Unable to initialize X11");
+}
+xc = new XlibCapture(dpy);
 }
 
 MjpegFrameCapture::~MjpegFrameCapture()
 {
+delete xc;
 XCloseDisplay(dpy);
 }
 
 void MjpegFrameCapture::Reset()
 {
 frame.clear();
-last_width = last_height = -1;
 }
 
 FrameInfo MjpegFrameCapture::CaptureFrame()
@@ -100,34 +102,20 @@ FrameInfo MjpegFrameCapture::CaptureFrame()
 }
 }
 
-int screen = XDefaultScreen(dpy);
-
-Window win = RootWindow(dpy, screen);
+XImg *image = xc->capture();
 
-XWindowAttributes win_info;
-XGetWindowAttributes(dpy, win, &win_info);
+bool is_first = image->new_resolution();
 
-bool is_first = false;
-if (win_info.width != last_width || win_info.height != last_height) {
-last_width = win_info.width;
-last_height = win_info.height;
-is_first = true;
-}
+info.size.width = image->width();
+info.size.height = image->height();
 
-info.size.width = win_info.width;
-info.size.height = win_info.height;
-
-int format = ZPixmap;
-// TODO handle errors
-XImage *image = XGetImage(dpy, win, win_info.x, win_info.y,
-  win_info.width, win_info.height, AllPlanes, 
format);
 
 // TODO handle errors
 // TODO multiple formats (only 32 bit)
-write_JPEG_file(frame, settings.quality, (uint8_t*) image->data,
-image->width, image->height);
+write_JPEG_file(frame, settings.quality, (uint8_t*) image->get_data(),
+image->width(), image->height());
 
-image->f.destroy_image(image);
+delete image;
 
 info.buffer = &frame[0];
 info.buffer_size = frame.size();
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server v3] Use (u)intptr_t for virtual addresses

2019-08-12 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 8/12/19 9:55 AM, Frediano Ziglio wrote:

On LLP64 platforms (like Windows) a virtual address cannot be
represented by a "unsigned long" type, so use uintptr_t which is
defined as an integral type large like a pointer.
"address_delta" and "addr_delta" are a difference of pointers so use
same type size.

Signed-off-by: Frediano Ziglio 
---
Changes since v2:
- use uintptr_t for address_delta and addr_delta

Changes since v1:
- fixed typo in commit message
- changed addr_delta type to match address_delta
---
  server/memslot.c   | 22 --
  server/memslot.h   | 20 ++--
  server/red-parse-qxl.c |  2 +-
  server/spice-qxl.h |  4 ++--
  4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/server/memslot.c b/server/memslot.c
index 2a1771b02..91d0284bd 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -21,7 +21,7 @@
  
  #include "memslot.h"
  
-static unsigned long __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)

+static uintptr_t __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)
  {
  return addr & info->memslot_clean_virt_mask;
  }
@@ -37,7 +37,8 @@ static void print_memslots(RedMemSlotInfo *info)
  !info->mem_slots[i][x].virt_end_addr) {
  continue;
  }
-printf("id %d, group %d, virt start %lx, virt end %lx, generation %u, 
delta %lx\n",
+printf("id %d, group %d, virt start %" PRIxPTR ", virt end %" PRIxPTR 
", generation %u,"
+   " delta %" PRIxPTR "\n",
 x, i, info->mem_slots[i][x].virt_start_addr,
 info->mem_slots[i][x].virt_end_addr, 
info->mem_slots[i][x].generation,
 info->mem_slots[i][x].address_delta);
@@ -46,7 +47,7 @@ static void print_memslots(RedMemSlotInfo *info)
  }
  
  /* return 1 if validation successfull, 0 otherwise */

-int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int 
slot_id,
+int memslot_validate_virt(RedMemSlotInfo *info, uintptr_t virt, int slot_id,
uint32_t add_size, uint32_t group_id)
  {
  MemSlot *slot;
@@ -60,8 +61,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  if (virt < slot->virt_start_addr || (virt + add_size) > 
slot->virt_end_addr) {
  print_memslots(info);
  spice_warning("virtual address out of range"
-  "virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-  "slot=0x%lx-0x%lx delta=0x%lx",
+  "virt=0x%" G_GINTPTR_MODIFIER "x+0x%x slot_id=%d 
group_id=%d\n"
+  "slot=0x%" G_GINTPTR_MODIFIER "x-0x%" G_GINTPTR_MODIFIER "x"
+  " delta=0x%" G_GINTPTR_MODIFIER "x",
virt, add_size, slot_id, group_id,
slot->virt_start_addr, slot->virt_end_addr, 
slot->address_delta);
  return 0;
@@ -69,9 +71,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  return 1;
  }
  
-unsigned long memslot_max_size_virt(RedMemSlotInfo *info,

-unsigned long virt, int slot_id,
-uint32_t group_id)
+uintptr_t memslot_max_size_virt(RedMemSlotInfo *info,
+uintptr_t virt, int slot_id,
+uint32_t group_id)
  {
  MemSlot *slot;
  
@@ -91,7 +93,7 @@ void *memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size

  {
  int slot_id;
  int generation;
-unsigned long h_virt;
+uintptr_t h_virt;
  
  MemSlot *slot;
  
@@ -171,7 +173,7 @@ void memslot_info_destroy(RedMemSlotInfo *info)

  }
  
  void memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,

-   uint64_t addr_delta, unsigned long virt_start, 
unsigned long virt_end,
+   uintptr_t addr_delta, uintptr_t virt_start, 
uintptr_t virt_end,
 uint32_t generation)
  {
  spice_assert(info->num_memslots_groups > slot_group_id);
diff --git a/server/memslot.h b/server/memslot.h
index 00728c4b6..23bf58d34 100644
--- a/server/memslot.h
+++ b/server/memslot.h
@@ -25,9 +25,9 @@
  
  typedef struct MemSlot {

  int generation;
-unsigned long virt_start_addr;
-unsigned long virt_end_addr;
-long address_delta;
+uintptr_t virt_start_addr;
+uintptr_t virt_end_addr;
+uintptr_t address_delta;
  } MemSlot;
  
  typedef struct RedMemSlotInfo {

@@ -39,8 +39,8 @@ typedef struct RedMemSlotInfo {
  uint8_t memslot_id_shift;
  uint8_t memslot_gen_shift;
  uint8_t internal_groupslot_id;
-unsigned lon

Re: [Spice-devel] [PATCH spice-server] style: Specify the possibility of "pragma once" usage

2019-08-12 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 8/12/19 9:56 AM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  docs/spice_style.txt | 9 +
  1 file changed, 9 insertions(+)

diff --git a/docs/spice_style.txt b/docs/spice_style.txt
index e4d7fc6d1..89a550fb8 100644
--- a/docs/spice_style.txt
+++ b/docs/spice_style.txt
@@ -372,6 +372,15 @@ The macro may include additional information, e.g. a 
component. For example a fi
  
  Historically, some headers added underscores liberally, e.g. MY_MODULE_H_. This is neither necessary nor discouraged, although as a reminder, a leading underscore followed by a capital letter is reserved for the implementation and should not be used, so _MY_MODULE_H is, technically speaking, invalid C.
  
+Alternatively (recommended on newer code) you can use the `pragma once` directive, as:

+
+[source,c]
+
+#pragma once
+
+...
+
+
  Header inclusion
  
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH v3 spice-streaming-agent] gst-plugin: Shorten template declarations

2019-08-12 Thread Snir Sheriber
The typeUPtr templates are very similar except for the unref-function.
This patch is replacing the templates with a macro which also accepts
an unref-function and is using this macro to define all typeUPtr types.

Signed-off-by: Snir Sheriber 
---

-Update commit message
-Conform with spice style

---
 src/gst-plugin.cpp | 64 +++---
 1 file changed, 20 insertions(+), 44 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4d17dbc..f6991f4 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -38,43 +38,19 @@ struct GstreamerEncoderSettings
 std::vector> prop_pairs;
 };
 
-template 
-struct GstObjectDeleter {
-void operator()(T* p)
-{
-gst_object_unref(p);
-}
-};
-
-template 
-using GstObjectUPtr = std::unique_ptr>;
-
-struct GstCapsDeleter {
-void operator()(GstCaps* p)
-{
-gst_caps_unref(p);
-}
-};
-
-using GstCapsUPtr = std::unique_ptr;
-
-struct GstSampleDeleter {
-void operator()(GstSample* p)
-{
-gst_sample_unref(p);
-}
-};
-
-using GstSampleUPtr = std::unique_ptr;
-
-struct GstBufferDeleter {
-void operator()(GstBuffer* p)
-{
-gst_buffer_unref(p);
-}
-};
-
-using GstBufferUPtr = std::unique_ptr;
+#define DECLARE_UPTR(type, func) \
+struct type##Deleter {   \
+void operator()(type* p) \
+{\
+func(p); \
+}\
+};   \
+using type##UPtr = std::unique_ptr;
+
+DECLARE_UPTR(GstBuffer, gst_buffer_unref)
+DECLARE_UPTR(GstCaps, gst_caps_unref)
+DECLARE_UPTR(GstSample, gst_sample_unref)
+DECLARE_UPTR(GstElement, gst_object_unref)
 
 class GstreamerFrameCapture final : public FrameCapture
 {
@@ -96,7 +72,7 @@ private:
 #if XLIB_CAPTURE
 void xlib_capture();
 #endif
-GstObjectUPtr pipeline, capture, sink;
+GstElementUPtr pipeline, capture, sink;
 GstSampleUPtr sample;
 GstMapInfo map = {};
 uint32_t last_width = ~0u, last_height = ~0u;
@@ -210,7 +186,7 @@ GstElement *GstreamerFrameCapture::get_encoder_plugin(const 
GstreamerEncoderSett
 
 // Utility to add an element to a GstBin
 // This checks return value and update reference correctly
-void gst_bin_add(GstBin *bin, const GstObjectUPtr &elem)
+void gst_bin_add(GstBin *bin, const GstElementUPtr &elem)
 {
 if (::gst_bin_add(bin, elem.get())) {
 // ::gst_bin_add take ownership using floating references but
@@ -226,24 +202,24 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 {
 gboolean link;
 
-GstObjectUPtr pipeline(gst_pipeline_new("pipeline"));
+GstElementUPtr pipeline(gst_pipeline_new("pipeline"));
 if (!pipeline) {
 throw std::runtime_error("Gstreamer's pipeline element cannot be 
created");
 }
-GstObjectUPtr capture(get_capture_plugin(settings));
+GstElementUPtr capture(get_capture_plugin(settings));
 if (!capture) {
 throw std::runtime_error("Gstreamer's capture element cannot be 
created");
 }
-GstObjectUPtr 
convert(gst_element_factory_make("autovideoconvert", "convert"));
+GstElementUPtr convert(gst_element_factory_make("autovideoconvert", 
"convert"));
 if (!convert) {
 throw std::runtime_error("Gstreamer's 'autovideoconvert' element 
cannot be created");
 }
 GstCapsUPtr sink_caps;
-GstObjectUPtr encoder(get_encoder_plugin(settings, sink_caps));
+GstElementUPtr encoder(get_encoder_plugin(settings, sink_caps));
 if (!encoder) {
 throw std::runtime_error("Gstreamer's encoder element cannot be 
created");
 }
-GstObjectUPtr sink(gst_element_factory_make("appsink", 
"sink"));
+GstElementUPtr sink(gst_element_factory_make("appsink", "sink"));
 if (!sink) {
 throw std::runtime_error("Gstreamer's appsink element cannot be 
created");
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] Use (u)intptr_t for virtual addresses

2019-08-11 Thread Snir Sheriber


On 8/11/19 7:41 PM, Frediano Ziglio wrote:



On 8/11/19 3:12 PM, Frediano Ziglio wrote:



Hi

On 7/23/19 11:22 AM, Frediano Ziglio wrote:


  When to Say "a" or "an" | Pronunciation |
  EnglishClub

https://www.englishclub.com/pronunciation/a-an.htm
On LLP64 platforms (like Windows) a virtual address cannot
be represented by a "unsigned long" type, so use uintptr_t
which is defined as a integral type large like a pointer.


This sentence sounds a bit odd to me

should be integer?

C/C++ documentation classify these types as integral, not integer.

also s/a/an

fixed, thanks



"address_delta" is a difference of pointers so use same
type size.


Not a big deal but wouldn't be preferable to be consistent
with addr_delta?

It sounds reasonable, although the value came from
"addr_delta" field of QXLDevMemSlot
which is part of SPICE ABI (so cannot be changed).


Actually I thought to change address_delta to match everywhere to
uint64_t of addr_delta
can this delta be actually negative? seems not since it's coming
from addr_delta,wouldn't be
better to keep it unsigned

Snir.

The value is used only for addition and we support only two's 
complement architectures
so no difference between signed or unsigned in this case (only 
additions means no extension,

division or others).
Moving to uin64_t instead of intptr_t or uintptr_t would cause 64 bit 
arithmetic even on

32 bit architectures for no reasons.
Would be uintptr_t (all unsigned but 32 bit) fine?



Yes, sounds good.

Snir.




Snir.

Signed-off-by: Frediano Ziglio
---
  server/memslot.c   | 22 --
  server/memslot.h   | 20 ++--
  server/red-parse-qxl.c |  2 +-
  server/spice-qxl.h |  4 ++--
  4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/server/memslot.c b/server/memslot.c
index 2a1771b02..182d2b7e9 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -21,7 +21,7 @@
  
  #include "memslot.h"
  
-static unsigned long __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)

+static uintptr_t __get_clean_virt(RedMemSlotInfo *info, 
QXLPHYSICAL addr)
  {
  return addr & info->memslot_clean_virt_mask;
  }
@@ -37,7 +37,8 @@ static void print_memslots(RedMemSlotInfo 
*info)
  !info->mem_slots[i][x].virt_end_addr) {
  continue;
  }
-printf("id %d, group %d, virt start %lx, virt end %lx, 
generation %u, delta %lx\n",
+printf("id %d, group %d, virt start %" PRIxPTR ", virt end 
%" PRIxPTR ", generation %u,"
+   " delta %" PRIxPTR "\n",
 x, i, 
info->mem_slots[i][x].virt_start_addr,
 info->mem_slots[i][x].virt_end_addr, 
info->mem_slots[i][x].generation,
 info->mem_slots[i][x].address_delta);
@@ -46,7 +47,7 @@ static void print_memslots(RedMemSlotInfo 
*info)
  }
  
  /* return 1 if validation successfull, 0 otherwise */

-int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
+int memslot_validate_virt(RedMemSlotInfo *info, uintptr_t 
virt, int slot_id,
uint32_t add_size, uint32_t 
group_id)
  {
  MemSlot *slot;
@@ -60,8 +61,9 @@ int memslot_validate_virt(RedMemSlotInfo 
*info, unsigned long virt, int slot_id,
  if (virt < slot->virt_start_addr || (virt + add_size) > 
slot->virt_end_addr) {
  print_memslots(info);
  spice_warning("virtual address out of range"
-  "virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-  "slot=0x%lx-0x%lx delta=0x%lx",
+  "virt=0x%" G_GINTPTR_MODIFIER "x+0x%x slot_id=%d 
group_id=%d\n"
+  "slot=0x%" G_GINTPTR_MODIFIER "x-0x%" 
G_GINTPTR_MODIFIER "x"
+  " delta=0x%" G_GINTPTR_MODIFIER "x",
virt, add_size, slot_id, group_id,
slot->virt_start_addr, slot->virt_end_addr,

Re: [Spice-devel] [PATCH spice-server] Use (u)intptr_t for virtual addresses

2019-08-11 Thread Snir Sheriber


On 8/11/19 3:12 PM, Frediano Ziglio wrote:



Hi

On 7/23/19 11:22 AM, Frediano Ziglio wrote:


  When to Say "a" or "an" | Pronunciation | EnglishClub

https://www.englishclub.com/pronunciation/a-an.htm
On LLP64 platforms (like Windows) a virtual address cannot
be represented by a "unsigned long" type, so use uintptr_t
which is defined as a integral type large like a pointer.


This sentence sounds a bit odd to me

should be integer?

C/C++ documentation classify these types as integral, not integer.

also s/a/an

fixed, thanks



"address_delta" is a difference of pointers so use same
type size.


Not a big deal but wouldn't be preferable to be consistent with
addr_delta?

It sounds reasonable, although the value came from "addr_delta" field 
of QXLDevMemSlot

which is part of SPICE ABI (so cannot be changed).



Actually I thought to change address_delta to match everywhere to 
uint64_t of addr_delta
can this delta be actually negative? seems not since it's coming from 
addr_delta,wouldn't be

better to keep it unsigned

Snir.



Snir.

Signed-off-by: Frediano Ziglio
---
  server/memslot.c   | 22 --
  server/memslot.h   | 20 ++--
  server/red-parse-qxl.c |  2 +-
  server/spice-qxl.h |  4 ++--
  4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/server/memslot.c b/server/memslot.c
index 2a1771b02..182d2b7e9 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -21,7 +21,7 @@
  
  #include "memslot.h"
  
-static unsigned long __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)

+static uintptr_t __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL 
addr)
  {
  return addr & info->memslot_clean_virt_mask;
  }
@@ -37,7 +37,8 @@ static void print_memslots(RedMemSlotInfo *info)
  !info->mem_slots[i][x].virt_end_addr) {
  continue;
  }
-printf("id %d, group %d, virt start %lx, virt end %lx, 
generation %u, delta %lx\n",
+printf("id %d, group %d, virt start %" PRIxPTR ", virt end %" 
PRIxPTR ", generation %u,"
+   " delta %" PRIxPTR "\n",
 x, i, info->mem_slots[i][x].virt_start_addr,
 info->mem_slots[i][x].virt_end_addr, 
info->mem_slots[i][x].generation,
 info->mem_slots[i][x].address_delta);
@@ -46,7 +47,7 @@ static void print_memslots(RedMemSlotInfo *info)
  }
  
  /* return 1 if validation successfull, 0 otherwise */

-int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, 
int slot_id,
+int memslot_validate_virt(RedMemSlotInfo *info, uintptr_t virt, int 
slot_id,
uint32_t add_size, uint32_t group_id)
  {
  MemSlot *slot;
@@ -60,8 +61,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, 
unsigned long virt, int slot_id,
  if (virt < slot->virt_start_addr || (virt + add_size) > 
slot->virt_end_addr) {
  print_memslots(info);
  spice_warning("virtual address out of range"
-  "virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-  "slot=0x%lx-0x%lx delta=0x%lx",
+  "virt=0x%" G_GINTPTR_MODIFIER "x+0x%x slot_id=%d 
group_id=%d\n"
+  "slot=0x%" G_GINTPTR_MODIFIER "x-0x%" G_GINTPTR_MODIFIER 
"x"
+  " delta=0x%" G_GINTPTR_MODIFIER "x",
virt, add_size, slot_id, group_id,
slot->virt_start_addr, slot->virt_end_addr, 
slot->address_delta);
  return 0;
@@ -69,9 +71,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, 
unsigned long virt, int slot_id,
  return 1;
  }
  
-unsigned long memslot_max_size_virt(RedMemSlotInfo *info,

-unsigned long virt, int slot_id,
-uint32_t group_id)
+uintptr_t memslot_max_size_virt(RedMemSlotInfo *info,
+uintptr_t virt, int slot_id,
+uint32_t group_id)
  {
  MemSlot *slot;
  
@@ -91,7 +93,7 @@ void *memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size

  {
  int slot_id;
  int generation;
-unsigned long h_virt;
+uintptr_t h_virt;
  
  MemSlot *slot;
  
@@ -171,7 +173,7 @@ void memslot_info_destroy(RedMemSlotInfo *info)

  }
  
  v

Re: [Spice-devel] [RFC spice-streaming-agent 2/4] spice-streaming-agent: fully reset the capture loop on start/stop requests

2019-08-11 Thread Snir Sheriber

Hi,


On 8/6/19 6:34 PM, Kevin Pouget wrote:

With this patch, spice-streaming-agent exits the frame-sending loop
when START/STOP requests are received. This allows the recomputation
of the most suitable capture/encoding plugin, that may have been
updated with START/STOP message.

Signed-off-by: Kevin Pouget 
---
  src/spice-streaming-agent.cpp | 19 +--
  1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
index 49f5dc4..d274b5f 100644
--- a/src/spice-streaming-agent.cpp
+++ b/src/spice-streaming-agent.cpp
@@ -125,7 +125,8 @@ private:
  static constexpr uint32_t max_device_address_len = 255;
  };
  
-static bool streaming_requested = false;

+static bool capture_in_progress = false;
+static bool reset_requested = false;
  static bool quit_requested = false;
  static std::set client_codecs;
  
@@ -167,11 +168,12 @@ static void read_command_from_device(StreamPort &stream_port)

  }
  case STREAM_TYPE_START_STOP: {
  StartStopMessage msg = in_message.get_payload();
-streaming_requested = msg.start_streaming;
+capture_in_progress = msg.start_streaming;
  client_codecs = msg.client_codecs;
+reset_requested = true;
  
  syslog(LOG_INFO, "GOT START_STOP message -- request to %s streaming",

-   streaming_requested ? "START" : "STOP");
+   capture_in_progress ? "START" : "STOP");
  return;
  }}
  
@@ -233,20 +235,25 @@ do_capture(StreamPort &stream_port, FrameLog &frame_log, ConcreteAgent &agent)

  {
  unsigned int frame_count = 0;
  while (!quit_requested) {
-while (!quit_requested && !streaming_requested) {
+while (!quit_requested && !capture_in_progress) {
  read_command(stream_port, true);
  }
  
  if (quit_requested) {

  return;
  }
+reset_requested = false;
  
  syslog(LOG_INFO, "streaming starts now");

  uint64_t time_last = 0;
  
  std::unique_ptr capture(agent.GetBestFrameCapture(client_codecs));

  if (!capture) {
-throw std::runtime_error("cannot find a suitable capture system");
+syslog(LOG_ERR, "Error cannot find a suitable capture system");
+
+// wait until a new start/stop request arrives with a new list of 
codecs



Can you explain why you change it to a log message? in case of failure
how you'll get out of this loop? client codec types availability can change
in run time? or it can change only their preference?

Snir.


+capture_in_progress = false;
+continue;
  }
  
  std::vector display_info;

@@ -275,7 +282,7 @@ do_capture(StreamPort &stream_port, FrameLog &frame_log, 
ConcreteAgent &agent)
  syslog(LOG_ERR, "Empty device display info from the plugin");
  }
  
-while (!quit_requested && streaming_requested) {

+while (!quit_requested && !reset_requested && capture_in_progress) {
  if (++frame_count % 100 == 0) {
  syslog(LOG_DEBUG, "SENT %d frames", frame_count);
  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaming-agent 4/4] concrete-agent: prioritize requested codec for plugin selection

2019-08-11 Thread Snir Sheriber


On 8/6/19 6:34 PM, Kevin Pouget wrote:

This patch gives more priority to the requested video codecs when
selecting the FrameCapture plugin, instead of its hard-coded rank.



We may want to mention this priority also in the header file.

Snir.


The client_codecs storage structure is changed from 'set' to 'vector',
as the codec order is not preserved by the set structure..

Signed-off-by: Kevin Pouget 
---
  src/concrete-agent.cpp| 38 +--
  src/concrete-agent.hpp|  2 +-
  src/spice-streaming-agent.cpp |  2 +-
  src/stream-port.cpp   |  2 +-
  src/stream-port.hpp   |  4 ++--
  5 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/concrete-agent.cpp b/src/concrete-agent.cpp
index 336bd09..683fa26 100644
--- a/src/concrete-agent.cpp
+++ b/src/concrete-agent.cpp
@@ -111,7 +111,7 @@ void ConcreteAgent::LoadPlugin(const std::string 
&plugin_filename)
  }
  }
  
-FrameCapture *ConcreteAgent::GetBestFrameCapture(const std::set& codecs)

+FrameCapture *ConcreteAgent::GetBestFrameCapture(const 
std::vector& codecs)
  {
  std::vector>> sorted_plugins;
  
@@ -121,24 +121,24 @@ FrameCapture *ConcreteAgent::GetBestFrameCapture(const std::set
  }
  sort(sorted_plugins.rbegin(), sorted_plugins.rend());
  
-// return first not null

-for (const auto& plugin: sorted_plugins) {
-if (plugin.first == DontUse) {
-break;
-}
-// check client supports the codec
-if (codecs.find(plugin.second->VideoCodecType()) == codecs.end())
-continue;
-
-FrameCapture *capture;
-try {
-capture = plugin.second->CreateCapture();
-} catch (const std::exception &err) {
-syslog(LOG_ERR, "Error creating capture engine: %s", err.what());
-continue;
-}
-if (capture) {
-return capture;
+for (const auto& codec_type: codecs) {
+// find the plugin with the highest rank for this codec type
+for (const auto& plugin: sorted_plugins) {
+if (plugin.first == DontUse) {
+continue;
+}
+
+// check client supports the codec
+if (plugin.second->VideoCodecType() != codec_type) {
+continue;
+}
+
+try {
+return plugin.second->CreateCapture();
+} catch (const std::exception &err) {
+syslog(LOG_ERR, "Error creating capture engine: %s", 
err.what());
+continue;
+}
  }
  }
  return nullptr;
diff --git a/src/concrete-agent.hpp b/src/concrete-agent.hpp
index 6d1be35..0399bab 100644
--- a/src/concrete-agent.hpp
+++ b/src/concrete-agent.hpp
@@ -33,7 +33,7 @@ public:
  void Register(const std::shared_ptr& plugin) override;
  const ConfigureOption* Options() const override;
  void LoadPlugins(const std::string &directory);
-FrameCapture *GetBestFrameCapture(const std::set& 
codecs);
+FrameCapture *GetBestFrameCapture(const std::vector& 
codecs);
  __attribute__ ((format (printf, 2, 3)))
  void LogStat(const char* format, ...) override;
  private:
diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
index d274b5f..15c2732 100644
--- a/src/spice-streaming-agent.cpp
+++ b/src/spice-streaming-agent.cpp
@@ -128,7 +128,7 @@ private:
  static bool capture_in_progress = false;
  static bool reset_requested = false;
  static bool quit_requested = false;
-static std::set client_codecs;
+static std::vector client_codecs;
  
  static bool have_something_to_read(StreamPort &stream_port, bool blocking)

  {
diff --git a/src/stream-port.cpp b/src/stream-port.cpp
index 2670120..0d08d50 100644
--- a/src/stream-port.cpp
+++ b/src/stream-port.cpp
@@ -43,7 +43,7 @@ StartStopMessage 
InboundMessage::get_payload()
  }
  
  for (size_t i = 1; i <= data[0]; ++i) {

-msg.client_codecs.insert((SpiceVideoCodecType) data[i]);
+msg.client_codecs.push_back((SpiceVideoCodecType) data[i]);
  }
  
  return msg;

diff --git a/src/stream-port.hpp b/src/stream-port.hpp
index 08473f7..b2f7520 100644
--- a/src/stream-port.hpp
+++ b/src/stream-port.hpp
@@ -16,7 +16,7 @@
  #include 
  #include 
  #include 
-#include 
+#include 
  
  
  namespace spice {

@@ -45,7 +45,7 @@ public:
  struct StartStopMessage
  {
  bool start_streaming = false;
-std::set client_codecs;
+std::vector client_codecs;
  };
  
  struct InCapabilitiesMessage {};

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaming-agent 1/4] gst-plugin: allow the instantiation of multiple GST encoder plugins

2019-08-11 Thread Snir Sheriber

Hi,



Tested, seems to work well! switching is smooth, if codec fails
it falls back to mjpeg (not very loudly), no default gstreamer
codec currently. As mentioned i find this feature useful :)

another comment below


On 8/6/19 6:34 PM, Kevin Pouget wrote:

With this patch, spice-streaming-agent can be launched with multiple
Gstreamer video codecs enabled:


spice-streaming-agent -c gst.codec=vp8 -c gst.codec=vp9 ...

Signed-off-by: Kevin Pouget 
---
  src/gst-plugin.cpp | 50 --
  1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 6415ac0..5469647 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -102,7 +102,7 @@ class GstreamerPlugin final: public Plugin
  public:
  FrameCapture *CreateCapture() override;
  unsigned Rank() override;
-void ParseOptions(const ConfigureOption *options);
+void ParseOptions(const ConfigureOption *options, SpiceVideoCodecType 
codec);
  SpiceVideoCodecType VideoCodecType() const override {
  return settings.codec;
  }
@@ -431,8 +431,10 @@ unsigned GstreamerPlugin::Rank()
  return SoftwareMin;
  }
  
-void GstreamerPlugin::ParseOptions(const ConfigureOption *options)

+void GstreamerPlugin::ParseOptions(const ConfigureOption *options,  
SpiceVideoCodecType codec)
  {
+settings.codec = codec;
+
  for (; options->name; ++options) {
  const std::string name = options->name;
  const std::string value = options->value;
@@ -443,20 +445,6 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption 
*options)
  } catch (const std::exception &e) {
  throw std::runtime_error("Invalid value '" + value + "' for option 
'framerate'.");
  }
-} else if (name == "gst.codec") {
-if (value == "h264") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H264;
-} else if (value == "vp9") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP9;
-} else if (value == "vp8") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP8;
-} else if (value == "mjpeg") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_MJPEG;
-} else if (value == "h265") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H265;
-} else {
-throw std::runtime_error("Invalid value '" + value + "' for option 
'gst.codec'.");
-}
  } else if (name == "gst.encoder") {
  settings.encoder = value;
  } else if (name == "gst.prop") {
@@ -478,11 +466,35 @@ SPICE_STREAMING_AGENT_PLUGIN(agent)
  {
  gst_init(nullptr, nullptr);
  
-auto plugin = std::make_shared();

+auto options = agent->Options();
+for (; options->name; ++options) {
+const std::string name = options->name;
+const std::string value = options->value;
  
-plugin->ParseOptions(agent->Options());

+if (name == "gst.codec") {
+SpiceVideoCodecType codec_type;
+if (value == "mjpeg") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_MJPEG;
+} else if (value == "h264") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H264;
+} else if (value == "h265") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H265;
+} else if (value == "vp8") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP8;
+} else if (value == "vp9") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP9;
+} else {
+throw std::runtime_error("Invalid value '" + value + "' for option 
'gst.codec'.");
+}
+
+auto plugin = std::make_shared();
+plugin->ParseOptions(agent->Options(), codec_type);
+agent->Register(plugin);
+}
+}
  
-agent->Register(plugin);

+// no default value at the moment
+// (used to be h264, see GstreamerEncoderSettings::codec)


When moving to multiple codecs registration we may want to do
something more solid, for example checking for gstreamer's codec
availability before registering plugins or even trying to initialize the
pipeline before registration.

This will probably require more efforts, I'll try invest some time on 
that too.


Snir.


  
  return true;

  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] Use (u)intptr_t for virtual addresses

2019-08-11 Thread Snir Sheriber


On 8/11/19 2:56 PM, Snir Sheriber wrote:


Hi

On 7/23/19 11:22 AM, Frediano Ziglio wrote:




  When to Say "a" or "an" | Pronunciation | EnglishClub

https://www.englishclub.com/pronunciation/a-an.htm



Oops, wrong pasting, please ignore :P



On LLP64 platforms (like Windows) a virtual address cannot
be represented by a "unsigned long" type, so use uintptr_t
which is defined as a integral type large like a pointer.



This sentence sounds a bit odd to me

should be integer?

also s/a/an



"address_delta" is a difference of pointers so use same
type size.



Not a big deal but wouldn't be preferable to be consistent with 
addr_delta?


Snir.


Signed-off-by: Frediano Ziglio
---
  server/memslot.c   | 22 --
  server/memslot.h   | 20 ++--
  server/red-parse-qxl.c |  2 +-
  server/spice-qxl.h |  4 ++--
  4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/server/memslot.c b/server/memslot.c
index 2a1771b02..182d2b7e9 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -21,7 +21,7 @@
  
  #include "memslot.h"
  
-static unsigned long __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)

+static uintptr_t __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)
  {
  return addr & info->memslot_clean_virt_mask;
  }
@@ -37,7 +37,8 @@ static void print_memslots(RedMemSlotInfo *info)
  !info->mem_slots[i][x].virt_end_addr) {
  continue;
  }
-printf("id %d, group %d, virt start %lx, virt end %lx, generation %u, 
delta %lx\n",
+printf("id %d, group %d, virt start %" PRIxPTR ", virt end %" PRIxPTR 
", generation %u,"
+   " delta %" PRIxPTR "\n",
 x, i, info->mem_slots[i][x].virt_start_addr,
 info->mem_slots[i][x].virt_end_addr, 
info->mem_slots[i][x].generation,
 info->mem_slots[i][x].address_delta);
@@ -46,7 +47,7 @@ static void print_memslots(RedMemSlotInfo *info)
  }
  
  /* return 1 if validation successfull, 0 otherwise */

-int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int 
slot_id,
+int memslot_validate_virt(RedMemSlotInfo *info, uintptr_t virt, int slot_id,
uint32_t add_size, uint32_t group_id)
  {
  MemSlot *slot;
@@ -60,8 +61,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  if (virt < slot->virt_start_addr || (virt + add_size) > 
slot->virt_end_addr) {
  print_memslots(info);
  spice_warning("virtual address out of range"
-  "virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-  "slot=0x%lx-0x%lx delta=0x%lx",
+  "virt=0x%" G_GINTPTR_MODIFIER "x+0x%x slot_id=%d 
group_id=%d\n"
+  "slot=0x%" G_GINTPTR_MODIFIER "x-0x%" G_GINTPTR_MODIFIER "x"
+  " delta=0x%" G_GINTPTR_MODIFIER "x",
virt, add_size, slot_id, group_id,
slot->virt_start_addr, slot->virt_end_addr, 
slot->address_delta);
  return 0;
@@ -69,9 +71,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  return 1;
  }
  
-unsigned long memslot_max_size_virt(RedMemSlotInfo *info,

-unsigned long virt, int slot_id,
-uint32_t group_id)
+uintptr_t memslot_max_size_virt(RedMemSlotInfo *info,
+uintptr_t virt, int slot_id,
+uint32_t group_id)
  {
  MemSlot *slot;
  
@@ -91,7 +93,7 @@ void *memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size

  {
  int slot_id;
  int generation;
-unsigned long h_virt;
+uintptr_t h_virt;
  
  MemSlot *slot;
  
@@ -171,7 +173,7 @@ void memslot_info_destroy(RedMemSlotInfo *info)

  }
  
  void memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,

-   uint64_t addr_delta, unsigned long virt_start, 
unsigned long virt_end,
+   uint64_t addr_delta, uintptr_t virt_start, 
uintptr_t virt_end,
 uint32_t generation)
  {
  spice_assert(info->num_memslots_groups > slot_group_id);
diff --git a/server/memslot.h b/server/memslot.h
index 00728c4b6..45381feb9 100644
--- a/server/memslot.h
+++ b/server/memslot.h
@@ -25,9 +25,9 @@
  
  typedef struct MemSlot {

  int generation;
-unsigned long virt_start_addr;
-unsigned long virt_end_addr;
-long address_delta;
+uintptr_t virt_start_addr;
+uintptr_t virt_end_addr;
+intptr_t address_delta;
  } MemSlot;
  
  typedef struct RedMemSlotInfo {


Re: [Spice-devel] [PATCH spice-server] Use (u)intptr_t for virtual addresses

2019-08-11 Thread Snir Sheriber

Hi

On 7/23/19 11:22 AM, Frediano Ziglio wrote:




  When to Say "a" or "an" | Pronunciation | EnglishClub

https://www.englishclub.com/pronunciation/a-an.htm
On LLP64 platforms (like Windows) a virtual address cannot
be represented by a "unsigned long" type, so use uintptr_t
which is defined as a integral type large like a pointer.



This sentence sounds a bit odd to me

should be integer?

also s/a/an



"address_delta" is a difference of pointers so use same
type size.



Not a big deal but wouldn't be preferable to be consistent with addr_delta?

Snir.


Signed-off-by: Frediano Ziglio 
---
  server/memslot.c   | 22 --
  server/memslot.h   | 20 ++--
  server/red-parse-qxl.c |  2 +-
  server/spice-qxl.h |  4 ++--
  4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/server/memslot.c b/server/memslot.c
index 2a1771b02..182d2b7e9 100644
--- a/server/memslot.c
+++ b/server/memslot.c
@@ -21,7 +21,7 @@
  
  #include "memslot.h"
  
-static unsigned long __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)

+static uintptr_t __get_clean_virt(RedMemSlotInfo *info, QXLPHYSICAL addr)
  {
  return addr & info->memslot_clean_virt_mask;
  }
@@ -37,7 +37,8 @@ static void print_memslots(RedMemSlotInfo *info)
  !info->mem_slots[i][x].virt_end_addr) {
  continue;
  }
-printf("id %d, group %d, virt start %lx, virt end %lx, generation %u, 
delta %lx\n",
+printf("id %d, group %d, virt start %" PRIxPTR ", virt end %" PRIxPTR 
", generation %u,"
+   " delta %" PRIxPTR "\n",
 x, i, info->mem_slots[i][x].virt_start_addr,
 info->mem_slots[i][x].virt_end_addr, 
info->mem_slots[i][x].generation,
 info->mem_slots[i][x].address_delta);
@@ -46,7 +47,7 @@ static void print_memslots(RedMemSlotInfo *info)
  }
  
  /* return 1 if validation successfull, 0 otherwise */

-int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int 
slot_id,
+int memslot_validate_virt(RedMemSlotInfo *info, uintptr_t virt, int slot_id,
uint32_t add_size, uint32_t group_id)
  {
  MemSlot *slot;
@@ -60,8 +61,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  if (virt < slot->virt_start_addr || (virt + add_size) > 
slot->virt_end_addr) {
  print_memslots(info);
  spice_warning("virtual address out of range"
-  "virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-  "slot=0x%lx-0x%lx delta=0x%lx",
+  "virt=0x%" G_GINTPTR_MODIFIER "x+0x%x slot_id=%d 
group_id=%d\n"
+  "slot=0x%" G_GINTPTR_MODIFIER "x-0x%" G_GINTPTR_MODIFIER "x"
+  " delta=0x%" G_GINTPTR_MODIFIER "x",
virt, add_size, slot_id, group_id,
slot->virt_start_addr, slot->virt_end_addr, 
slot->address_delta);
  return 0;
@@ -69,9 +71,9 @@ int memslot_validate_virt(RedMemSlotInfo *info, unsigned long 
virt, int slot_id,
  return 1;
  }
  
-unsigned long memslot_max_size_virt(RedMemSlotInfo *info,

-unsigned long virt, int slot_id,
-uint32_t group_id)
+uintptr_t memslot_max_size_virt(RedMemSlotInfo *info,
+uintptr_t virt, int slot_id,
+uint32_t group_id)
  {
  MemSlot *slot;
  
@@ -91,7 +93,7 @@ void *memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size

  {
  int slot_id;
  int generation;
-unsigned long h_virt;
+uintptr_t h_virt;
  
  MemSlot *slot;
  
@@ -171,7 +173,7 @@ void memslot_info_destroy(RedMemSlotInfo *info)

  }
  
  void memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,

-   uint64_t addr_delta, unsigned long virt_start, 
unsigned long virt_end,
+   uint64_t addr_delta, uintptr_t virt_start, 
uintptr_t virt_end,
 uint32_t generation)
  {
  spice_assert(info->num_memslots_groups > slot_group_id);
diff --git a/server/memslot.h b/server/memslot.h
index 00728c4b6..45381feb9 100644
--- a/server/memslot.h
+++ b/server/memslot.h
@@ -25,9 +25,9 @@
  
  typedef struct MemSlot {

  int generation;
-unsigned long virt_start_addr;
-unsigned long virt_end_addr;
-long address_delta;
+uintptr_t virt_start_addr;
+uintptr_t virt_end_addr;
+intptr_t address_delta;
  } MemSlot;
  
  typedef struct RedMemSlotInfo {

@@ -39,8 +39,8 @@ typedef struct RedMemSlotInfo {
  uint8_t memslot_id_shift;
  uint8_t memslot_gen_shift;
  uint8_t internal_groupslot_id;
-unsigned long memslot_gen_mask;
-unsigned long memslot_clean_virt_mask;
+uintptr_t memslot_gen_mask;
+uintptr_t memslot_clean_virt_mask;
  } RedMemSlotInfo;
  
  static inline int memslot_g

Re: [Spice-devel] [PATCH spice-gtk] Use "#pragma once" instead of preprocessor guards

2019-08-11 Thread Snir Sheriber


Oh, just noticed, if this pushed, we may want to change the spice
style doc as well

Snir.

On 8/11/19 12:01 PM, Snir Sheriber wrote:

Hi,

It could be an issue with duplicated name headers but
seems we do not have such headers.

Ack

On 7/29/19 5:23 PM, Frediano Ziglio wrote:

Guards currently are quite different in format.
Unify updating to "#pragma once" syntax. This syntax is used
by GTK tools too.
To avoid possible regression public headers are left untouched.


I guess it's better to go safe ;)

Snir.



Signed-off-by: Frediano Ziglio 
---
  src/bio-gio.h   | 5 +
  src/channel-display-priv.h  | 5 +
  src/channel-playback-priv.h | 4 +---
  src/channel-usbredir-priv.h | 5 +
  src/client_sw_canvas.h  | 5 +
  src/continuation.h  | 4 +---
  src/coroutine.h | 4 +---
  src/decode.h    | 5 +
  src/desktop-integration.h   | 5 +
  src/gio-coroutine.h | 5 +
  src/giopipe.h   | 5 +
  src/smartcard-manager-priv.h    | 5 +
  src/spice-audio-priv.h  | 5 +
  src/spice-channel-cache.h   | 5 +
  src/spice-channel-priv.h    | 5 +
  src/spice-common.h  | 5 +
  src/spice-file-transfer-task-priv.h | 5 +
  src/spice-grabsequence-priv.h   | 5 +
  src/spice-gstaudio.h    | 5 +
  src/spice-gtk-session-priv.h    | 5 +
  src/spice-pulse.h   | 5 +
  src/spice-session-priv.h    | 5 +
  src/spice-uri-priv.h    | 5 +
  src/spice-util-priv.h   | 5 +
  src/spice-widget-priv.h | 5 +
  src/usb-acl-helper.h    | 5 +
  src/usb-backend.h   | 5 +
  src/usb-device-manager-priv.h   | 5 +
  src/usbdk_api.h | 4 +---
  src/usbutil.h   | 4 +---
  src/vmcstream.h | 5 +
  src/vncdisplaykeymap.h  | 5 +
  32 files changed, 32 insertions(+), 123 deletions(-)

diff --git a/src/bio-gio.h b/src/bio-gio.h
index 31fd3693..7f41ce10 100644
--- a/src/bio-gio.h
+++ b/src/bio-gio.h
@@ -15,8 +15,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
<http://www.gnu.org/licenses/>.

  */
-#ifndef BIO_GIO_H_
-# define BIO_GIO_H_
+#pragma once
    #include 
  #include 
@@ -26,5 +25,3 @@ G_BEGIN_DECLS
  BIO* bio_new_giostream(GIOStream *stream);
    G_END_DECLS
-
-#endif /* !BIO_GIO_H_ */
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 16c12c6e..b5d67285 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -15,8 +15,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
<http://www.gnu.org/licenses/>.

  */
-#ifndef CHANNEL_DISPLAY_PRIV_H_
-# define CHANNEL_DISPLAY_PRIV_H_
+#pragma once
    #include 
  #ifdef WIN32
@@ -203,5 +202,3 @@ gboolean hand_pipeline_to_widget(display_stream 
*st,  GstPipeline *pipeline);

  void spice_frame_free(SpiceFrame *frame);
    G_END_DECLS
-
-#endif // CHANNEL_DISPLAY_PRIV_H_
diff --git a/src/channel-playback-priv.h b/src/channel-playback-priv.h
index aa33d2c4..19ccc150 100644
--- a/src/channel-playback-priv.h
+++ b/src/channel-playback-priv.h
@@ -15,10 +15,8 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
<http://www.gnu.org/licenses/>.

  */
-#ifndef __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
-#define __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+#pragma once
    gboolean spice_playback_channel_is_active(SpicePlaybackChannel 
*channel);
  guint32 spice_playback_channel_get_latency(SpicePlaybackChannel 
*channel);
  void spice_playback_channel_sync_latency(SpicePlaybackChannel 
*channel);

-#endif
diff --git a/src/channel-usbredir-priv.h b/src/channel-usbredir-priv.h
index 80cd31f6..a36f5d9b 100644
--- a/src/channel-usbredir-priv.h
+++ b/src/channel-usbredir-priv.h
@@ -18,8 +18,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
<http://www.gnu.org/licenses/>.

  */
-#ifndef __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
-#define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
+#pragma once
    #ifdef USE_USBREDIR
  @@ -76,5 +75,3 @@ int 
spice_usbredir_write_callback(SpiceUsbredirChannel *channel, uint8_t 
*data,

  G_END_DECLS
    #endif /* USE_USBREDIR */
-
-#endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */
diff --git a/src/client_sw_canvas.h b/src/client_sw_canvas.h
index 1180c5b6..ac30240f 100644
--- a/src/client_sw_canvas.h
+++ b/src/client_sw_canvas.h
@@ -15,11 +15,8 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this li

Re: [Spice-devel] [PATCH spice-server] red-replay-qxl: Fix replay on 32 bit systems

2019-08-11 Thread Snir Sheriber

Hi,

Acked-by: Snir Sheriber 

nice catch

Snir.

On 7/23/19 11:22 AM, Frediano Ziglio wrote:

On 32 systems pointers are 32 bit while QXLPHYSICAL is always
64 bit.
Using pointer -> intptr_t -> QXLPHYSICAL conversion cause pointers
to have higher 32 bit set to 1 if the address is >= 0x8000.
This is possible depending on address space.
The QXLPHYSICAL is split in 3 sections:
- slot ID;
- generation;
- virtual address.
Current utility using record file (spice-server-replay) set slot ID
and generation to 0 so if the higher bits become all 1 slot ID and
generation won't be 0 causing the utility to fail.
Use pointer -> uintptr_t -> QXLPHYSICAL conversion to avoid this
issue.
Note that for opposite conversion (QXLPHYSICAL_TO_PTR) the conversion
does not change, type is changed just for consistency.

Signed-off-by: Frediano Ziglio 
---
  server/red-replay-qxl.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/red-replay-qxl.c b/server/red-replay-qxl.c
index 674feae2f..b38c4cdbd 100644
--- a/server/red-replay-qxl.c
+++ b/server/red-replay-qxl.c
@@ -29,8 +29,8 @@
  #include "memslot.h"
  #include "red-parse-qxl.h"
  
-#define QXLPHYSICAL_FROM_PTR(ptr) ((QXLPHYSICAL)(intptr_t)(ptr))

-#define QXLPHYSICAL_TO_PTR(phy) ((void*)(intptr_t)(phy))
+#define QXLPHYSICAL_FROM_PTR(ptr) ((QXLPHYSICAL)(uintptr_t)(ptr))
+#define QXLPHYSICAL_TO_PTR(phy) ((void*)(uintptr_t)(phy))
  
  typedef enum {

  REPLAY_OK = 0,

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server 1/2] replay: Remove some goto statement

2019-08-11 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 7/23/19 11:22 AM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  server/tests/replay.c | 18 ++
  1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/server/tests/replay.c b/server/tests/replay.c
index e3ef7bf15..992f26d63 100644
--- a/server/tests/replay.c
+++ b/server/tests/replay.c
@@ -116,7 +116,7 @@ static gboolean fill_queue_idle(gpointer user_data)
  if (!cmd) {
  g_async_queue_push(display_queue, GINT_TO_POINTER(-1));
  g_async_queue_push(cursor_queue, GINT_TO_POINTER(-1));
-goto end;
+break;
  }
  
  ++ncommands;

@@ -133,7 +133,6 @@ static gboolean fill_queue_idle(gpointer user_data)
  }
  }
  
-end:

  if (!keep) {
  pthread_mutex_lock(&mutex);
  if (fill_source) {
@@ -153,17 +152,12 @@ static void fill_queue(void)
  {
  pthread_mutex_lock(&mutex);
  
-if (!started)

-goto end;
-
-if (fill_source)
-goto end;
-
-fill_source = g_idle_source_new();
-g_source_set_callback(fill_source, fill_queue_idle, NULL, NULL);
-g_source_attach(fill_source, basic_event_loop_get_context());
+if (started && fill_source == NULL) {
+fill_source = g_idle_source_new();
+g_source_set_callback(fill_source, fill_queue_idle, NULL, NULL);
+g_source_attach(fill_source, basic_event_loop_get_context());
+}
  
-end:

  pthread_mutex_unlock(&mutex);
  }
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] Use "#pragma once" instead of preprocessor guards

2019-08-11 Thread Snir Sheriber

Hi,

It could be an issue with duplicated name headers but
seems we do not have such headers.

Ack

On 7/29/19 5:23 PM, Frediano Ziglio wrote:

Guards currently are quite different in format.
Unify updating to "#pragma once" syntax. This syntax is used
by GTK tools too.
To avoid possible regression public headers are left untouched.


I guess it's better to go safe ;)

Snir.



Signed-off-by: Frediano Ziglio 
---
  src/bio-gio.h   | 5 +
  src/channel-display-priv.h  | 5 +
  src/channel-playback-priv.h | 4 +---
  src/channel-usbredir-priv.h | 5 +
  src/client_sw_canvas.h  | 5 +
  src/continuation.h  | 4 +---
  src/coroutine.h | 4 +---
  src/decode.h| 5 +
  src/desktop-integration.h   | 5 +
  src/gio-coroutine.h | 5 +
  src/giopipe.h   | 5 +
  src/smartcard-manager-priv.h| 5 +
  src/spice-audio-priv.h  | 5 +
  src/spice-channel-cache.h   | 5 +
  src/spice-channel-priv.h| 5 +
  src/spice-common.h  | 5 +
  src/spice-file-transfer-task-priv.h | 5 +
  src/spice-grabsequence-priv.h   | 5 +
  src/spice-gstaudio.h| 5 +
  src/spice-gtk-session-priv.h| 5 +
  src/spice-pulse.h   | 5 +
  src/spice-session-priv.h| 5 +
  src/spice-uri-priv.h| 5 +
  src/spice-util-priv.h   | 5 +
  src/spice-widget-priv.h | 5 +
  src/usb-acl-helper.h| 5 +
  src/usb-backend.h   | 5 +
  src/usb-device-manager-priv.h   | 5 +
  src/usbdk_api.h | 4 +---
  src/usbutil.h   | 4 +---
  src/vmcstream.h | 5 +
  src/vncdisplaykeymap.h  | 5 +
  32 files changed, 32 insertions(+), 123 deletions(-)

diff --git a/src/bio-gio.h b/src/bio-gio.h
index 31fd3693..7f41ce10 100644
--- a/src/bio-gio.h
+++ b/src/bio-gio.h
@@ -15,8 +15,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
.
  */
-#ifndef BIO_GIO_H_
-# define BIO_GIO_H_
+#pragma once
  
  #include 

  #include 
@@ -26,5 +25,3 @@ G_BEGIN_DECLS
  BIO* bio_new_giostream(GIOStream *stream);
  
  G_END_DECLS

-
-#endif /* !BIO_GIO_H_ */
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 16c12c6e..b5d67285 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -15,8 +15,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
.
  */
-#ifndef CHANNEL_DISPLAY_PRIV_H_
-# define CHANNEL_DISPLAY_PRIV_H_
+#pragma once
  
  #include 

  #ifdef WIN32
@@ -203,5 +202,3 @@ gboolean hand_pipeline_to_widget(display_stream *st,  
GstPipeline *pipeline);
  void spice_frame_free(SpiceFrame *frame);
  
  G_END_DECLS

-
-#endif // CHANNEL_DISPLAY_PRIV_H_
diff --git a/src/channel-playback-priv.h b/src/channel-playback-priv.h
index aa33d2c4..19ccc150 100644
--- a/src/channel-playback-priv.h
+++ b/src/channel-playback-priv.h
@@ -15,10 +15,8 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
.
  */
-#ifndef __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
-#define __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+#pragma once
  
  gboolean spice_playback_channel_is_active(SpicePlaybackChannel *channel);

  guint32 spice_playback_channel_get_latency(SpicePlaybackChannel *channel);
  void spice_playback_channel_sync_latency(SpicePlaybackChannel *channel);
-#endif
diff --git a/src/channel-usbredir-priv.h b/src/channel-usbredir-priv.h
index 80cd31f6..a36f5d9b 100644
--- a/src/channel-usbredir-priv.h
+++ b/src/channel-usbredir-priv.h
@@ -18,8 +18,7 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
.
  */
-#ifndef __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
-#define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
+#pragma once
  
  #ifdef USE_USBREDIR
  
@@ -76,5 +75,3 @@ int spice_usbredir_write_callback(SpiceUsbredirChannel *channel, uint8_t *data,

  G_END_DECLS
  
  #endif /* USE_USBREDIR */

-
-#endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */
diff --git a/src/client_sw_canvas.h b/src/client_sw_canvas.h
index 1180c5b6..ac30240f 100644
--- a/src/client_sw_canvas.h
+++ b/src/client_sw_canvas.h
@@ -15,11 +15,8 @@
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see 
.
  */
-#ifndef __SPICE_CLIENT_SW_CANVAS_H__
-#define __SPICE_CLIENT_SW_CANVAS_H__
+#pragma once
  
  #define SW_CANVAS_CACHE
  
 

[Spice-devel] [PATCH v2 spice-streaming-agent 2/2] gst-plugin: Shorten template declarations

2019-08-10 Thread Snir Sheriber
Signed-off-by: Snir Sheriber 
---
Another suggestion to shoten the templates + changing subject
---
 src/gst-plugin.cpp | 64 +++---
 1 file changed, 20 insertions(+), 44 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4d17dbc..703d5b2 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -38,43 +38,19 @@ struct GstreamerEncoderSettings
 std::vector> prop_pairs;
 };
 
-template 
-struct GstObjectDeleter {
-void operator()(T* p)
-{
-gst_object_unref(p);
-}
-};
-
-template 
-using GstObjectUPtr = std::unique_ptr>;
-
-struct GstCapsDeleter {
-void operator()(GstCaps* p)
-{
-gst_caps_unref(p);
-}
-};
-
-using GstCapsUPtr = std::unique_ptr;
-
-struct GstSampleDeleter {
-void operator()(GstSample* p)
-{
-gst_sample_unref(p);
-}
-};
-
-using GstSampleUPtr = std::unique_ptr;
-
-struct GstBufferDeleter {
-void operator()(GstBuffer* p)
-{
-gst_buffer_unref(p);
-}
-};
-
-using GstBufferUPtr = std::unique_ptr;
+#define DECLARE_UPTR(type, func) \
+struct type##Deleter { \
+void operator()(type* p) \
+{ \
+func(p); \
+} \
+}; \
+using type##UPtr = std::unique_ptr; \
+
+DECLARE_UPTR(GstBuffer, gst_buffer_unref)
+DECLARE_UPTR(GstCaps, gst_caps_unref)
+DECLARE_UPTR(GstSample, gst_sample_unref)
+DECLARE_UPTR(GstElement, gst_object_unref)
 
 class GstreamerFrameCapture final : public FrameCapture
 {
@@ -96,7 +72,7 @@ private:
 #if XLIB_CAPTURE
 void xlib_capture();
 #endif
-GstObjectUPtr pipeline, capture, sink;
+GstElementUPtr pipeline, capture, sink;
 GstSampleUPtr sample;
 GstMapInfo map = {};
 uint32_t last_width = ~0u, last_height = ~0u;
@@ -210,7 +186,7 @@ GstElement *GstreamerFrameCapture::get_encoder_plugin(const 
GstreamerEncoderSett
 
 // Utility to add an element to a GstBin
 // This checks return value and update reference correctly
-void gst_bin_add(GstBin *bin, const GstObjectUPtr &elem)
+void gst_bin_add(GstBin *bin, const GstElementUPtr &elem)
 {
 if (::gst_bin_add(bin, elem.get())) {
 // ::gst_bin_add take ownership using floating references but
@@ -226,24 +202,24 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 {
 gboolean link;
 
-GstObjectUPtr pipeline(gst_pipeline_new("pipeline"));
+GstElementUPtr pipeline(gst_pipeline_new("pipeline"));
 if (!pipeline) {
 throw std::runtime_error("Gstreamer's pipeline element cannot be 
created");
 }
-GstObjectUPtr capture(get_capture_plugin(settings));
+GstElementUPtr capture(get_capture_plugin(settings));
 if (!capture) {
 throw std::runtime_error("Gstreamer's capture element cannot be 
created");
 }
-GstObjectUPtr 
convert(gst_element_factory_make("autovideoconvert", "convert"));
+GstElementUPtr convert(gst_element_factory_make("autovideoconvert", 
"convert"));
 if (!convert) {
 throw std::runtime_error("Gstreamer's 'autovideoconvert' element 
cannot be created");
 }
 GstCapsUPtr sink_caps;
-GstObjectUPtr encoder(get_encoder_plugin(settings, sink_caps));
+GstElementUPtr encoder(get_encoder_plugin(settings, sink_caps));
 if (!encoder) {
 throw std::runtime_error("Gstreamer's encoder element cannot be 
created");
 }
-GstObjectUPtr sink(gst_element_factory_make("appsink", 
"sink"));
+GstElementUPtr sink(gst_element_factory_make("appsink", "sink"));
 if (!sink) {
 throw std::runtime_error("Gstreamer's appsink element cannot be 
created");
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH v2 spice-streaming-agent 1/2] gst-plugin: Free input buffer and XImage as soon as possible

2019-08-10 Thread Snir Sheriber
This also fixes a memory leak of GstBuffer

Signed-off-by: Snir Sheriber 
---
Changes from v1:
-commit message
-Style
--
 src/gst-plugin.cpp | 36 +++-
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 0a1d041..4d17dbc 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -67,6 +67,15 @@ struct GstSampleDeleter {
 
 using GstSampleUPtr = std::unique_ptr;
 
+struct GstBufferDeleter {
+void operator()(GstBuffer* p)
+{
+gst_buffer_unref(p);
+}
+};
+
+using GstBufferUPtr = std::unique_ptr;
+
 class GstreamerFrameCapture final : public FrameCapture
 {
 public:
@@ -86,7 +95,6 @@ private:
 Display *const dpy;
 #if XLIB_CAPTURE
 void xlib_capture();
-XImage *image = nullptr;
 #endif
 GstObjectUPtr pipeline, capture, sink;
 GstSampleUPtr sample;
@@ -306,12 +314,6 @@ void GstreamerFrameCapture::free_sample()
 gst_buffer_unmap(gst_sample_get_buffer(sample.get()), &map);
 sample.reset();
 }
-#if XLIB_CAPTURE
-if(image) {
-image->f.destroy_image(image);
-image = nullptr;
-}
-#endif
 }
 
 GstreamerFrameCapture::~GstreamerFrameCapture()
@@ -327,6 +329,12 @@ void GstreamerFrameCapture::Reset()
 }
 
 #if XLIB_CAPTURE
+void free_ximage(gpointer data)
+{
+XImage *image = (XImage*)data;
+image->f.destroy_image(image);
+}
+
 void GstreamerFrameCapture::xlib_capture()
 {
 int screen = XDefaultScreen(dpy);
@@ -349,14 +357,16 @@ void GstreamerFrameCapture::xlib_capture()
 gst_element_set_state(pipeline.get(), GST_STATE_PLAYING);
 }
 
-image = XGetImage(dpy, win, 0, 0,
-  cur_width, cur_height, AllPlanes, ZPixmap);
+XImage *image = XGetImage(dpy, win, 0, 0,
+  cur_width, cur_height, AllPlanes, ZPixmap);
 if (!image) {
 throw std::runtime_error("Cannot capture from X");
 }
 
-GstBuffer *buf;
-buf = gst_buffer_new_wrapped(image->data, image->height * 
image->bytes_per_line);
+GstBufferUPtr 
buf(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, 
image->data,
+  image->height * 
image->bytes_per_line, 0,
+  image->height * 
image->bytes_per_line, image,
+  free_ximage));
 if (!buf) {
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
@@ -368,8 +378,8 @@ void GstreamerFrameCapture::xlib_capture()
  "framerate", GST_TYPE_FRACTION, 
settings.fps, 1,
  nullptr));
 
-// Push sample
-GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, 
nullptr));
+// Push sample (gst_app_src_push_sample does not take buffer ownership)
+GstSampleUPtr appsrc_sample(gst_sample_new(buf.get(), caps.get(), nullptr, 
nullptr));
 if (gst_app_src_push_sample(GST_APP_SRC(capture.get()), 
appsrc_sample.get()) != GST_FLOW_OK) {
 throw std::runtime_error("gstramer appsrc element cannot push sample");
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-gtk 1/2] streaming: make draw-area visible on MJPEG encoder creation

2019-08-08 Thread Snir Sheriber

Hi,


On 8/8/19 1:09 PM, Kevin Pouget wrote:

Hello,

On Thu, Aug 8, 2019 at 11:23 AM Snir Sheriber  wrote:

Hi,

On 8/7/19 6:49 PM, Kevin Pouget wrote:

This patch allows the MJPEG encoder to inform the spice-widget that
its video drawing area (draw-area) should be made visible on screen.

So the first one does not work?

it was working, but the patch was more a workaround than a proper fix,
this call:


+gtk_stack_set_visible_child_name(d->stack, "draw-area");

was triggered too often, ie also when switching between GST streams
(but the gst-area would be put back on top right after)


BTW i think the consensus is to mention the patch version in all
of the subjects (not only in the cover letter)

yes, sorry, I wanted to post this as a reply to the previous email,
but git forgot to ask me the in-reply-to value, I don't know why :#



This is required to switch from GST video decoding to native MJPEG
decoding, otherwise the gst-area remained on top and the MJPEG video
stream was never shown.

Actually IIRC the first version of the gst-overlay signal included
a boolean value which could have been useful here :P

you mean an earlier version, or the one modified by this patch?


Earlier version


I wondered if it would be an acceptable solution to hack the existing
set_overlay function,
for instance if pipeline_ptr == NULL, then set the native drawing area



I'm not sure how bad is it, at least it shouldn't damage.



Signed-off-by: Kevin Pouget

---
   src/channel-display-mjpeg.c |  2 ++
   src/channel-display-priv.h  |  2 +-
   src/channel-display.c   | 38 ++---
   src/spice-marshal.txt   |  1 +
   src/spice-widget.c  | 16 ++--
   5 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
index 647d31b..6f1a4d7 100644
--- a/src/channel-display-mjpeg.c
+++ b/src/channel-display-mjpeg.c
@@ -300,5 +300,7 @@ VideoDecoder* create_mjpeg_decoder(int codec_type, 
display_stream *stream)

   /* All the other fields are initialized to zero by g_new0(). */

+show_mjpeg_widget(stream);
+
   return (VideoDecoder*)decoder;
   }
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 16c12c6..3424a8e 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -199,7 +199,7 @@ void stream_dropped_frame_on_playback(display_stream *st);
   void stream_display_frame(display_stream *st, SpiceFrame *frame, uint32_t 
width, uint32_t height, int stride, uint8_t* data);
   guintptr get_window_handle(display_stream *st);
   gboolean hand_pipeline_to_widget(display_stream *st,  GstPipeline *pipeline);
-
+gboolean show_mjpeg_widget(display_stream *st);
   void spice_frame_free(SpiceFrame *frame);

   G_END_DECLS
diff --git a/src/channel-display.c b/src/channel-display.c
index 44555e3..18e95b9 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -90,7 +90,8 @@ enum {
   SPICE_DISPLAY_MARK,
   SPICE_DISPLAY_GL_DRAW,
   SPICE_DISPLAY_STREAMING_MODE,
-SPICE_DISPLAY_OVERLAY,
+SPICE_DISPLAY_GST_OVERLAY,
+SPICE_DISPLAY_MJPEG_OVERLAY,

The term overlay is derived from GstVideoOverlay which is an gstreamer
interface that overlays gstreamer output on the gtk widget, in the case
of builtin mjpeg (also with gst is not always true) we pass pixels and
render into the surface I don't think the name should invlude "overlay".

actually, I also don't really like to have "mjpeg" in the name,
because GST also supports it,
maybe SPICE_DISPLAY_NATIVE_DRAW_AREA



Sounds better.



   SPICE_DISPLAY_LAST_SIGNAL,
   };
@@ -491,7 +492,7 @@ static void 
spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
*
* Since: 0.36
**/
-signals[SPICE_DISPLAY_OVERLAY] =
+signals[SPICE_DISPLAY_GST_OVERLAY] =
   g_signal_new("gst-video-overlay",
G_OBJECT_CLASS_TYPE(gobject_class),
0, 0,
@@ -501,6 +502,25 @@ static void 
spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
1,
GST_TYPE_PIPELINE);

+/**
+ * SpiceDisplayChannel::mjpeg-video-overlay:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ *
+ * The #SpiceDisplayChannel::mjpeg-video-overlay signal is emitted
+ * when the MJPEG encoder is ready and its drawing area should be
+ * made visible on screen
+ *
+ * Since: 0.37
+ **/
+signals[SPICE_DISPLAY_MJPEG_OVERLAY] =
+g_signal_new("mjpeg-video-overlay",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ 0, 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN,
+ 0);
+
   channel_set_handlers(SPICE_CHANNEL_CLASS(klass));

Re: [Spice-devel] [RFC spice-gtk 1/2] streaming: make draw-area visible on MJPEG encoder creation

2019-08-08 Thread Snir Sheriber

Hi,

On 8/7/19 6:49 PM, Kevin Pouget wrote:

This patch allows the MJPEG encoder to inform the spice-widget that
its video drawing area (draw-area) should be made visible on screen.



So the first one does not work?

BTW i think the consensus is to mention the patch version in all
of the subjects (not only in the cover letter)



This is required to switch from GST video decoding to native MJPEG
decoding, otherwise the gst-area remained on top and the MJPEG video
stream was never shown.



Actually IIRC the first version of the gst-overlay signal included
a boolean value which could have been useful here :P




Signed-off-by: Kevin Pouget 

---
  src/channel-display-mjpeg.c |  2 ++
  src/channel-display-priv.h  |  2 +-
  src/channel-display.c   | 38 ++---
  src/spice-marshal.txt   |  1 +
  src/spice-widget.c  | 16 ++--
  5 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
index 647d31b..6f1a4d7 100644
--- a/src/channel-display-mjpeg.c
+++ b/src/channel-display-mjpeg.c
@@ -300,5 +300,7 @@ VideoDecoder* create_mjpeg_decoder(int codec_type, 
display_stream *stream)

  /* All the other fields are initialized to zero by g_new0(). */

+show_mjpeg_widget(stream);
+
  return (VideoDecoder*)decoder;
  }
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 16c12c6..3424a8e 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -199,7 +199,7 @@ void stream_dropped_frame_on_playback(display_stream *st);
  void stream_display_frame(display_stream *st, SpiceFrame *frame, uint32_t 
width, uint32_t height, int stride, uint8_t* data);
  guintptr get_window_handle(display_stream *st);
  gboolean hand_pipeline_to_widget(display_stream *st,  GstPipeline *pipeline);
-
+gboolean show_mjpeg_widget(display_stream *st);
  void spice_frame_free(SpiceFrame *frame);

  G_END_DECLS
diff --git a/src/channel-display.c b/src/channel-display.c
index 44555e3..18e95b9 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -90,7 +90,8 @@ enum {
  SPICE_DISPLAY_MARK,
  SPICE_DISPLAY_GL_DRAW,
  SPICE_DISPLAY_STREAMING_MODE,
-SPICE_DISPLAY_OVERLAY,
+SPICE_DISPLAY_GST_OVERLAY,
+SPICE_DISPLAY_MJPEG_OVERLAY,


The term overlay is derived from GstVideoOverlay which is an gstreamer
interface that overlays gstreamer output on the gtk widget, in the case
of builtin mjpeg (also with gst is not always true) we pass pixels and
render into the surface I don't think the name should invlude "overlay".




  SPICE_DISPLAY_LAST_SIGNAL,
  };
@@ -491,7 +492,7 @@ static void 
spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
   *
   * Since: 0.36
   **/
-signals[SPICE_DISPLAY_OVERLAY] =
+signals[SPICE_DISPLAY_GST_OVERLAY] =
  g_signal_new("gst-video-overlay",
   G_OBJECT_CLASS_TYPE(gobject_class),
   0, 0,
@@ -501,6 +502,25 @@ static void 
spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
   1,
   GST_TYPE_PIPELINE);

+/**
+ * SpiceDisplayChannel::mjpeg-video-overlay:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ *
+ * The #SpiceDisplayChannel::mjpeg-video-overlay signal is emitted
+ * when the MJPEG encoder is ready and its drawing area should be
+ * made visible on screen
+ *
+ * Since: 0.37
+ **/
+signals[SPICE_DISPLAY_MJPEG_OVERLAY] =
+g_signal_new("mjpeg-video-overlay",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ 0, 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN,
+ 0);
+
  channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
  }

@@ -1472,12 +1492,24 @@ gboolean hand_pipeline_to_widget(display_stream *st, 
GstPipeline *pipeline)
  gboolean res = false;

  if (st->surface->streaming_mode) {
-g_signal_emit(st->channel, signals[SPICE_DISPLAY_OVERLAY], 0,
+g_signal_emit(st->channel, signals[SPICE_DISPLAY_GST_OVERLAY], 0,
pipeline, &res);
  }
  return res;
  }

+G_GNUC_INTERNAL
+gboolean show_mjpeg_widget(display_stream *st)
+{
+gboolean res = false;
+g_warning("SHOW!");


I guess this was for testing purposes.



+if (st->surface->streaming_mode) {
+g_signal_emit(st->channel, signals[SPICE_DISPLAY_MJPEG_OVERLAY], 0, 
&res);
+}
+
+return res;
+}
+
  /* after a sequence of 3 drops, push a report to the server, even
   * if the report window is bigger */
  #define STREAM_REPORT_DROP_SEQ_LEN_LIMIT 3
diff --git a/src/spice-marshal.txt b/src/spice-marshal.txt
index 46be405..e60d725 100644
--- a/src/spice-marshal.txt
+++ b/src/spice-marshal.txt
@@ -8,6 +8,7 @@ VOID:POINTER,INT
  VOID:POINTER,BOOLEAN
  BOOLEAN:POINT

Re: [Spice-devel] [PATCH 1/3] Add copr Makefile

2019-08-05 Thread Snir Sheriber

Hi,

On 8/5/19 7:11 PM, Frediano Ziglio wrote:

Hi Snir,
   there were some notes at
https://patchwork.freedesktop.org/patch/288568/?series=57199&rev=1
and
https://patchwork.freedesktop.org/patch/288569/?series=57199&rev=1


This patch [2/3] is not needed we pushed another one which
extracts the deps from the spec file.



some not addressed.
Also patch #3 was merged, maybe would be worth to send an updated
version.
(series at https://patchwork.freedesktop.org/series/57199/)



Yes, sorry, i pinged the wrong one, there's v2, I'll ping it now.




We already have Copr set up for SPICE server. How would you like to
proceed? Move all to Gitlab? How is the integration with SPICE server?


Yes we do, and it's generated from a script running in a vm
when we push to spice-server's git repo

The idea is to drop the necessity of a vm that generates the copr builds.
In order to this in spice server we need to add the copr makefile and
also it's better to have the spec file inside the repo.



You referred to a hook to setup on Gitlab, which systems are you
going to use? Fedora Copr I imagine.



Yes, Fedora Copr, gitlab and that's it.

The way it works is you configure gitlab (in gitlab project 
settings->integration)
to trigger the copr repo webhook link with every push (this will trigger 
a build

in copr, this build is based on srpm created by the .copr/Makefile script)


Snir.


Frediano


ping


On 2/25/19 4:56 PM, Snir Sheriber wrote:

---
   .copr/Makefile | 21 +
   1 file changed, 21 insertions(+)
   create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..53b1b1b
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,21 @@
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = make automake autoconf autoconf-archive libtool xz gcc-c++ fedpkg
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol ; ./autogen.sh ; make install
+
+   # get dependencies
+   dnf install -y `grep BuildRequires\: spice-streaming-agent.spec.in | awk
'{$$1=""; print $$0}' | sed "s/\bspice-protocol\b// ; s/>.*//" | tr -s
"\n" " "`
+   # build this project
+   PKG_CONFIG_PATH=/usr/local/share/pkgconfig ./autogen.sh
+
+   # create source rpm
+   sed -i -E "s/(^Release:[[:space:]]*)([^%]*)/\1`date
+'%Y%m%d%H%M.spice.nigthly'`/" spice-streaming-agent.spec
+   make dist
+   md5sum *tar* | head -n1 > "sources"
+   fedpkg --release "epel7" --path . srpm
+   cp *src.rpm $(outdir)

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH v2 spice-streaming-agent] Add copr Makefile

2019-08-05 Thread Snir Sheriber

ping


On 2/27/19 1:26 PM, Snir Sheriber wrote:

This Makefile script is invoked by copr to build source rpm
See: https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm
---

Changes from v1 are script improvements and description

---
  .copr/Makefile | 21 +
  1 file changed, 21 insertions(+)
  create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..0ae3bed
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,21 @@
+# This Makefile script is invoked by copr to build source rpm
+# See: https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm
+
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = make automake autoconf autoconf-archive libtool xz git rpm-build
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol && ./autogen.sh --prefix=/usr/ && make install
+
+   # get other dependencies for project excluding spice-protocol
+   dnf install -y `sed '/^BuildRequires:/!d; s/.*://; s/\bspice-protocol\b//; 
s/>.*//' *.spec.in`
+
+   # create source rpm
+   ./autogen.sh
+   sed -i -E "s/(^Release:[[:space:]]*)([^%]*)/\1`date 
+'%Y%m%d%H%M.spice.nigthly'`/" *.spec
+   make dist
+   rpmbuild -bs *.spec --define "_sourcedir $$PWD" --define "_srcrpmdir 
$(outdir)"

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH 1/3] Add copr Makefile

2019-08-05 Thread Snir Sheriber

ping


On 2/25/19 4:56 PM, Snir Sheriber wrote:

---
  .copr/Makefile | 21 +
  1 file changed, 21 insertions(+)
  create mode 100644 .copr/Makefile

diff --git a/.copr/Makefile b/.copr/Makefile
new file mode 100644
index 000..53b1b1b
--- /dev/null
+++ b/.copr/Makefile
@@ -0,0 +1,21 @@
+PROTOCOL_GIT_REPO = https://gitlab.freedesktop.org/spice/spice-protocol
+BUILD = make automake autoconf autoconf-archive libtool xz gcc-c++ fedpkg
+
+srpm:
+   dnf install -y $(BUILD)
+
+   # get upstream spice protocol
+   git clone $(PROTOCOL_GIT_REPO)
+   cd spice-protocol ; ./autogen.sh ; make install
+
+   # get dependencies
+   dnf install -y `grep BuildRequires\: spice-streaming-agent.spec.in | awk '{$$1=""; print $$0}' | sed 
"s/\bspice-protocol\b// ; s/>.*//" | tr -s "\n" " "`
+   # build this project
+   PKG_CONFIG_PATH=/usr/local/share/pkgconfig ./autogen.sh
+
+   # create source rpm
+   sed -i -E "s/(^Release:[[:space:]]*)([^%]*)/\1`date 
+'%Y%m%d%H%M.spice.nigthly'`/" spice-streaming-agent.spec
+   make dist
+   md5sum *tar* | head -n1 > "sources"
+   fedpkg --release "epel7" --path . srpm
+   cp *src.rpm $(outdir)

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaming-agent 1/2] gst-plugin: allow the instantiation of multiple GST encoder plugins

2019-08-04 Thread Snir Sheriber

HI,

On 8/1/19 6:27 PM, Kevin Pouget wrote:

Hello Snir,

On Thu, Aug 1, 2019 at 5:02 PM Snir Sheriber  wrote:

Hi,


On 8/1/19 3:43 PM, Kevin Pouget wrote:

On Wed, Jul 31, 2019 at 12:09 PM Kevin Pouget  wrote:

On Wed, Jul 31, 2019 at 11:50 AM Frediano Ziglio  wrote:

With this patch, spice-streaming-agent can be launched with multiple
Gstreamer video codecs enabled:


spice-streaming-agent -c gst.codec=vp8 -c gst.codec=vp9 ...

---
   src/gst-plugin.cpp | 50 --
   1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..6252e42 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -102,7 +102,7 @@ class GstreamerPlugin final: public Plugin
   public:
   FrameCapture *CreateCapture() override;
   unsigned Rank() override;
-void ParseOptions(const ConfigureOption *options);
+void ParseOptions(const ConfigureOption *options, SpiceVideoCodecType
codec);
   SpiceVideoCodecType VideoCodecType() const override {
   return settings.codec;
   }
@@ -419,8 +419,10 @@ unsigned GstreamerPlugin::Rank()
   return SoftwareMin;
   }

-void GstreamerPlugin::ParseOptions(const ConfigureOption *options)
+void GstreamerPlugin::ParseOptions(const ConfigureOption *options,
SpiceVideoCodecType codec)
   {
+settings.codec = codec;
+
   for (; options->name; ++options) {
   const std::string name = options->name;
   const std::string value = options->value;
@@ -431,20 +433,6 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption
*options)
   } catch (const std::exception &e) {
   throw std::runtime_error("Invalid value '" + value + "' for
   option 'framerate'.");
   }
-} else if (name == "gst.codec") {
-if (value == "h264") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H264;
-} else if (value == "vp9") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP9;
-} else if (value == "vp8") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP8;
-} else if (value == "mjpeg") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_MJPEG;
-} else if (value == "h265") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H265;
-} else {
-throw std::runtime_error("Invalid value '" + value + "' for
option 'gst.codec'.");
-}
   } else if (name == "gst.encoder") {
   settings.encoder = value;
   }
@@ -459,11 +447,35 @@ SPICE_STREAMING_AGENT_PLUGIN(agent)
   {
   gst_init(nullptr, nullptr);

-auto plugin = std::make_shared();
+auto options = agent->Options();
+for (; options->name; ++options) {
+const std::string name = options->name;
+const std::string value = options->value;

-plugin->ParseOptions(agent->Options());
+if (name == "gst.codec") {
+SpiceVideoCodecType codec_type;
+if (value == "mjpeg") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_MJPEG;
+} else if (value == "h264") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H264;
+} else if (value == "h265") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H265;
+} else if (value == "vp8") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP8;
+} else if (value == "vp9") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP9;
+} else {
+throw std::runtime_error("Invalid value '" + value + "' for
option 'gst.codec'.");
+}
+
+auto plugin = std::make_shared();
+plugin->ParseOptions(agent->Options(), codec_type);
+agent->Register(plugin);
+}
+}

-agent->Register(plugin);
+// no default value at the moment
+// (used to be h264, see GstreamerEncoderSettings::codec)

   return true;
   }

I didn't test it but it makes perfectly sense.
On the other hand I'm wondering what will happen to the other
parameters. They will be "broadcasted" to all plugins.
For "framerate" is fine but what will happen if you specify
also properties (gst.prop) and encoder (gst.encoder) ?

maybe the easiest is to say that "gst.XXX=YYY" applies to all the
codecs, and "gst.CODEC.XXX=YYY" is only for one codec, with
XXX=prop|encoder at the moment.

Hello,

I did the modifications below to allow passing codec-specific gst parameters:


Basically Gstreamer properties are more tied to the encoder than
the codec type e.g. vaapih264enc plugin has

Re: [Spice-devel] [PATCH spice-streaming-agent 4/4] gst-plugin: reduce number of templates being used

2019-08-04 Thread Snir Sheriber


On 8/1/19 7:17 PM, Frediano Ziglio wrote:

---

This patch is not really necessary, just a suggestion, it's a bit hacky
but would save some code.
Other options would be to use explicit template specialization or to
leave it as is.


Sure, what I don't like is that is surely not type safe, you can instantiate
a GstMiniObjectUPtr of whatever, even an "int" type and compiler won't
complain at all, witch is a good thing of C++.
I'm thinking possible changes to this patch like traits and/or macros to
declare allowed types.
Certain the type is getting a bit long ("GstMiniObjectUPtr"),
but this could be solve by typedefs (well, this was solved by using lines).


What about:


template 
struct is_gst_mini_type {
};

template ::type>
struct GstMiniObjectDeleter {
 void operator()(T* p)
 {
 gst_mini_object_unref(GST_MINI_OBJECT_CAST(p));
 }
};

template 
using GstMiniObjectUPtr = std::unique_ptr>;

#define DECLARE_GST_MINI_TYPE(name) \
template <> struct is_gst_mini_type { \
 typedef name *type; \
}; \
using name ## UPtr = GstMiniObjectUPtr;

DECLARE_GST_MINI_TYPE(GstSample)



Actually also the GstObjectUPtr is not really type safe

I'm not sure i wouldn't prefer to just do something like this for
simplicity:

template 
struct GstDeleter {
    void operator()(T* p)
    {
    gst_object_unref(p);
    }
};

template <>
struct GstDeleter  {
    void operator()(GstCaps* p)
    {
    gst_caps_unref(p);
    }
};

template <>
struct GstDeleter  {
    void operator()(GstSample* p)
    {
    gst_sample_unref(p);
    }
};

template <>
struct GstDeleter  {
    void operator()(GstBuffer* p)
    {
    gst_buffer_unref(p);
    }
};

template 
using GstUPtr = std::unique_ptr>;

Snir.


---
  src/gst-plugin.cpp | 44 ++--
  1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index c7412c5..5f4cc3d 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -49,32 +49,16 @@ struct GstObjectDeleter {
  template 
  using GstObjectUPtr = std::unique_ptr>;
  
-struct GstCapsDeleter {

-void operator()(GstCaps* p)
-{
-gst_caps_unref(p);
-}
-};
-
-using GstCapsUPtr = std::unique_ptr;
-
-struct GstSampleDeleter {
-void operator()(GstSample* p)
-{
-gst_sample_unref(p);
-}
-};
-
-using GstSampleUPtr = std::unique_ptr;
-
-struct GstBufferDeleter {
-void operator()(GstBuffer* p)
+template 
+struct GstMiniObjectDeleter {
+void operator()(T* p)
  {
-gst_buffer_unref(p);
+gst_mini_object_unref(GST_MINI_OBJECT_CAST(p));
  }
  };
  
-using GstBufferUPtr = std::unique_ptr;

+template 
+using GstMiniObjectUPtr = std::unique_ptr>;
  
  class GstreamerFrameCapture final : public FrameCapture

  {
@@ -89,7 +73,7 @@ public:
  std::vector get_device_display_info() const
  override;
  private:
  void free_sample();
-GstElement *get_encoder_plugin(const GstreamerEncoderSettings
&settings,
GstCapsUPtr &sink_caps);
+GstElement *get_encoder_plugin(const GstreamerEncoderSettings
&settings,
GstMiniObjectUPtr &sink_caps);
  GstElement *get_capture_plugin(const GstreamerEncoderSettings
  &settings);
  void pipeline_init(const GstreamerEncoderSettings &settings);
  Display *const dpy;
@@ -97,7 +81,7 @@ private:
  void xlib_capture();
  #endif
  GstObjectUPtr pipeline, capture, sink;
-GstSampleUPtr sample;
+GstMiniObjectUPtr sample;
  GstMapInfo map = {};
  uint32_t last_width = ~0u, last_height = ~0u;
  uint32_t cur_width = 0, cur_height = 0;
@@ -134,7 +118,7 @@ GstElement
*GstreamerFrameCapture::get_capture_plugin(const GstreamerEncoderSett
  }
  
  GstElement *GstreamerFrameCapture::get_encoder_plugin(const

  GstreamerEncoderSettings &settings,
-  GstCapsUPtr
&sink_caps)
+
GstMiniObjectUPtr
&sink_caps)
  {
  GList *encoders;
  GList *filtered;
@@ -238,7 +222,7 @@ void GstreamerFrameCapture::pipeline_init(const
GstreamerEncoderSettings &settin
  if (!convert) {
  throw std::runtime_error("Gstreamer's 'autovideoconvert' element
  cannot be created");
  }
-GstCapsUPtr sink_caps;
+GstMiniObjectUPtr sink_caps;
  GstObjectUPtr encoder(get_encoder_plugin(settings,
  sink_caps));
  if (!encoder) {
  throw std::runtime_error("Gstreamer's encoder element cannot be
  created");
@@ -260,7 +244,7 @@ void GstreamerFrameCapture::pipeline_init(const
GstreamerEncoderSettings &settin
  gst_bin_add(bin, encoder);
  gst_bin_add(bin, sink);
  
-GstCapsUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));

+GstMiniObjectUPtr
caps(gst_caps_from_string("video/x-raw(ANY)"));
  link = gst_element_link(capture.get(), convert.get()) &&
 gst_element_link_filtered(convert.get(), encoder.get(),
 caps.get()) &&
 gst_element_link_filtered(encoder.get(), 

Re: [Spice-devel] [PATCH spice-streaming-agent 1/4] gst-plugin: Allow ANY memory type to pass from convertor to encoder

2019-08-04 Thread Snir Sheriber


On 8/1/19 6:30 PM, Frediano Ziglio wrote:

Looks fine.

But what are the difference? For instance what additional memory types we
want to feed to the pipeline?



For example VASurface for vaapi based plugins

Snir


---
  src/gst-plugin.cpp | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 6415ac0..e9d9364 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -252,7 +252,7 @@ void GstreamerFrameCapture::pipeline_init(const
GstreamerEncoderSettings &settin
  gst_bin_add(bin, encoder);
  gst_bin_add(bin, sink);
  
-GstCapsUPtr caps(gst_caps_from_string("video/x-raw"));

+GstCapsUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));
  link = gst_element_link(capture.get(), convert.get()) &&
 gst_element_link_filtered(convert.get(), encoder.get(),
 caps.get()) &&
 gst_element_link_filtered(encoder.get(), sink.get(),
 sink_caps.get());

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-streaming-agent 3/4] gst-plugin: Free input buffer and XImage as soon as possible

2019-08-04 Thread Snir Sheriber

Hi,


On 8/1/19 6:39 PM, Frediano Ziglio wrote:

---
  src/gst-plugin.cpp | 31 ---
  1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 0a1d041..c7412c5 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -67,6 +67,15 @@ struct GstSampleDeleter {
  
  using GstSampleUPtr = std::unique_ptr;
  
+struct GstBufferDeleter {

+void operator()(GstBuffer* p)
+{
+gst_buffer_unref(p);
+}
+};
+
+using GstBufferUPtr = std::unique_ptr;
+
  class GstreamerFrameCapture final : public FrameCapture
  {
  public:
@@ -86,7 +95,6 @@ private:
  Display *const dpy;
  #if XLIB_CAPTURE
  void xlib_capture();
-XImage *image = nullptr;
  #endif
  GstObjectUPtr pipeline, capture, sink;
  GstSampleUPtr sample;
@@ -306,12 +314,6 @@ void GstreamerFrameCapture::free_sample()
  gst_buffer_unmap(gst_sample_get_buffer(sample.get()), &map);
  sample.reset();
  }
-#if XLIB_CAPTURE
-if(image) {
-image->f.destroy_image(image);
-image = nullptr;
-}
-#endif
  }
  
  GstreamerFrameCapture::~GstreamerFrameCapture()

@@ -327,9 +329,14 @@ void GstreamerFrameCapture::Reset()
  }
  
  #if XLIB_CAPTURE

+void free_ximage(gpointer data) {

bracket on next line


+((XImage*)data)->f.destroy_image((XImage*)data);
+}
+
  void GstreamerFrameCapture::xlib_capture()
  {
  int screen = XDefaultScreen(dpy);
+XImage *image = nullptr;
  

I would declare + initialize on the same line



Sure



  Window win = RootWindow(dpy, screen);
  XWindowAttributes win_info;
@@ -355,9 +362,11 @@ void GstreamerFrameCapture::xlib_capture()
  throw std::runtime_error("Cannot capture from X");
  }
  
-GstBuffer *buf;

-buf = gst_buffer_new_wrapped(image->data, image->height *
image->bytes_per_line);
-if (!buf) {
+GstBufferUPtr buf(gst_buffer_new_wrapped_full((GstMemoryFlags)0,
image->data,
+  image->height *
image->bytes_per_line, 0,
+  image->height *
image->bytes_per_line, image,
+  free_ximage));
+if (!buf.get()) {
  throw std::runtime_error("Failed to wrap image in gstreamer
  buffer");
  }
  
@@ -369,7 +378,7 @@ void GstreamerFrameCapture::xlib_capture()

   nullptr));
  
  // Push sample

-GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr,
nullptr));
+GstSampleUPtr appsrc_sample(gst_sample_new(buf.get(), caps.get(),
nullptr, nullptr));

I'm a bit confused on reference counting here.
The change seems to indicate that now "buf" is freed automatically
(as the unique_ptr).
So, is this patch also fixing a memory leak ?



Indeed, forgot to mention, this was unnoticeable in common usage.
I noticed that leak only when i worked on this patch .

The issue is with the push_sample function which in oppose to push_buffer,
does not take ownership.

Snir.


  if (gst_app_src_push_sample(GST_APP_SRC(capture.get()),
  appsrc_sample.get()) != GST_FLOW_OK) {
  throw std::runtime_error("gstramer appsrc element cannot push
  sample");
  }

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] usb-device-manager: Remove unused parameter from spice_usb_device_manager_device_match

2019-08-01 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 8/1/19 4:04 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  src/usb-device-manager.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 0a04b119..426a0cd7 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -733,8 +733,8 @@ static void 
spice_usb_device_manager_auto_connect_cb(GObject  *gobject,
  }
  
  static gboolean

-spice_usb_device_manager_device_match(SpiceUsbDeviceManager *self, 
SpiceUsbDevice *device,
-  const int bus, const int address)
+spice_usb_device_match(SpiceUsbDevice *device,
+   const int bus, const int address)
  {
  return (spice_usb_device_get_busnum(device) == bus &&
  spice_usb_device_get_devaddr(device) == address);
@@ -750,7 +750,7 @@ spice_usb_device_manager_find_device(SpiceUsbDeviceManager 
*self,
  
  for (i = 0; i < priv->devices->len; i++) {

  curr = g_ptr_array_index(priv->devices, i);
-if (spice_usb_device_manager_device_match(self, curr, bus, address)) {
+if (spice_usb_device_match(curr, bus, address)) {
  device = curr;
  break;
  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [RFC spice-streaming-agent 1/2] gst-plugin: allow the instantiation of multiple GST encoder plugins

2019-08-01 Thread Snir Sheriber

Hi,


On 8/1/19 3:43 PM, Kevin Pouget wrote:

On Wed, Jul 31, 2019 at 12:09 PM Kevin Pouget  wrote:

On Wed, Jul 31, 2019 at 11:50 AM Frediano Ziglio  wrote:

With this patch, spice-streaming-agent can be launched with multiple
Gstreamer video codecs enabled:


spice-streaming-agent -c gst.codec=vp8 -c gst.codec=vp9 ...

---
  src/gst-plugin.cpp | 50 --
  1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..6252e42 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -102,7 +102,7 @@ class GstreamerPlugin final: public Plugin
  public:
  FrameCapture *CreateCapture() override;
  unsigned Rank() override;
-void ParseOptions(const ConfigureOption *options);
+void ParseOptions(const ConfigureOption *options, SpiceVideoCodecType
codec);
  SpiceVideoCodecType VideoCodecType() const override {
  return settings.codec;
  }
@@ -419,8 +419,10 @@ unsigned GstreamerPlugin::Rank()
  return SoftwareMin;
  }

-void GstreamerPlugin::ParseOptions(const ConfigureOption *options)
+void GstreamerPlugin::ParseOptions(const ConfigureOption *options,
SpiceVideoCodecType codec)
  {
+settings.codec = codec;
+
  for (; options->name; ++options) {
  const std::string name = options->name;
  const std::string value = options->value;
@@ -431,20 +433,6 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption
*options)
  } catch (const std::exception &e) {
  throw std::runtime_error("Invalid value '" + value + "' for
  option 'framerate'.");
  }
-} else if (name == "gst.codec") {
-if (value == "h264") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H264;
-} else if (value == "vp9") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP9;
-} else if (value == "vp8") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_VP8;
-} else if (value == "mjpeg") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_MJPEG;
-} else if (value == "h265") {
-settings.codec = SPICE_VIDEO_CODEC_TYPE_H265;
-} else {
-throw std::runtime_error("Invalid value '" + value + "' for
option 'gst.codec'.");
-}
  } else if (name == "gst.encoder") {
  settings.encoder = value;
  }
@@ -459,11 +447,35 @@ SPICE_STREAMING_AGENT_PLUGIN(agent)
  {
  gst_init(nullptr, nullptr);

-auto plugin = std::make_shared();
+auto options = agent->Options();
+for (; options->name; ++options) {
+const std::string name = options->name;
+const std::string value = options->value;

-plugin->ParseOptions(agent->Options());
+if (name == "gst.codec") {
+SpiceVideoCodecType codec_type;
+if (value == "mjpeg") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_MJPEG;
+} else if (value == "h264") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H264;
+} else if (value == "h265") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_H265;
+} else if (value == "vp8") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP8;
+} else if (value == "vp9") {
+codec_type = SPICE_VIDEO_CODEC_TYPE_VP9;
+} else {
+throw std::runtime_error("Invalid value '" + value + "' for
option 'gst.codec'.");
+}
+
+auto plugin = std::make_shared();
+plugin->ParseOptions(agent->Options(), codec_type);
+agent->Register(plugin);
+}
+}

-agent->Register(plugin);
+// no default value at the moment
+// (used to be h264, see GstreamerEncoderSettings::codec)

  return true;
  }

I didn't test it but it makes perfectly sense.
On the other hand I'm wondering what will happen to the other
parameters. They will be "broadcasted" to all plugins.
For "framerate" is fine but what will happen if you specify
also properties (gst.prop) and encoder (gst.encoder) ?

maybe the easiest is to say that "gst.XXX=YYY" applies to all the
codecs, and "gst.CODEC.XXX=YYY" is only for one codec, with
XXX=prop|encoder at the moment.

Hello,

I did the modifications below to allow passing codec-specific gst parameters:



Basically Gstreamer properties are more tied to the encoder than
the codec type e.g. vaapih264enc plugin has a property named "low-delay-b"
and x264enc hasn't.

Now I'm thinking maybe i should have allow to set properties only when the
encoder is specified :P, anyway i think we do need to parse it in order 
somehow
i.e. vp8 + its encoder + its props... , another vp8 + its props ... , 
h264 + its encoder...


I did no try it yet, I'll test it and have a closer look on everything, 
i like this feature!


Thanks,
Snir.





gst.codec=CODEC
gst.prop | gst.CODEC.prop
gst.encoder | gst.C

[Spice-devel] [PATCH spice-streaming-agent 3/4] gst-plugin: Free input buffer and XImage as soon as possible

2019-08-01 Thread Snir Sheriber
---
 src/gst-plugin.cpp | 31 ---
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 0a1d041..c7412c5 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -67,6 +67,15 @@ struct GstSampleDeleter {
 
 using GstSampleUPtr = std::unique_ptr;
 
+struct GstBufferDeleter {
+void operator()(GstBuffer* p)
+{
+gst_buffer_unref(p);
+}
+};
+
+using GstBufferUPtr = std::unique_ptr;
+
 class GstreamerFrameCapture final : public FrameCapture
 {
 public:
@@ -86,7 +95,6 @@ private:
 Display *const dpy;
 #if XLIB_CAPTURE
 void xlib_capture();
-XImage *image = nullptr;
 #endif
 GstObjectUPtr pipeline, capture, sink;
 GstSampleUPtr sample;
@@ -306,12 +314,6 @@ void GstreamerFrameCapture::free_sample()
 gst_buffer_unmap(gst_sample_get_buffer(sample.get()), &map);
 sample.reset();
 }
-#if XLIB_CAPTURE
-if(image) {
-image->f.destroy_image(image);
-image = nullptr;
-}
-#endif
 }
 
 GstreamerFrameCapture::~GstreamerFrameCapture()
@@ -327,9 +329,14 @@ void GstreamerFrameCapture::Reset()
 }
 
 #if XLIB_CAPTURE
+void free_ximage(gpointer data) {
+((XImage*)data)->f.destroy_image((XImage*)data);
+}
+
 void GstreamerFrameCapture::xlib_capture()
 {
 int screen = XDefaultScreen(dpy);
+XImage *image = nullptr;
 
 Window win = RootWindow(dpy, screen);
 XWindowAttributes win_info;
@@ -355,9 +362,11 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Cannot capture from X");
 }
 
-GstBuffer *buf;
-buf = gst_buffer_new_wrapped(image->data, image->height * 
image->bytes_per_line);
-if (!buf) {
+GstBufferUPtr buf(gst_buffer_new_wrapped_full((GstMemoryFlags)0, 
image->data,
+  image->height * 
image->bytes_per_line, 0,
+  image->height * 
image->bytes_per_line, image,
+  free_ximage));
+if (!buf.get()) {
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
@@ -369,7 +378,7 @@ void GstreamerFrameCapture::xlib_capture()
  nullptr));
 
 // Push sample
-GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, 
nullptr));
+GstSampleUPtr appsrc_sample(gst_sample_new(buf.get(), caps.get(), nullptr, 
nullptr));
 if (gst_app_src_push_sample(GST_APP_SRC(capture.get()), 
appsrc_sample.get()) != GST_FLOW_OK) {
 throw std::runtime_error("gstramer appsrc element cannot push sample");
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent 4/4] gst-plugin: reduce number of templates being used

2019-08-01 Thread Snir Sheriber
---

This patch is not really necessary, just a suggestion, it's a bit hacky
but would save some code.
Other options would be to use explicit template specialization or to
leave it as is.

---
 src/gst-plugin.cpp | 44 ++--
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index c7412c5..5f4cc3d 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -49,32 +49,16 @@ struct GstObjectDeleter {
 template 
 using GstObjectUPtr = std::unique_ptr>;
 
-struct GstCapsDeleter {
-void operator()(GstCaps* p)
-{
-gst_caps_unref(p);
-}
-};
-
-using GstCapsUPtr = std::unique_ptr;
-
-struct GstSampleDeleter {
-void operator()(GstSample* p)
-{
-gst_sample_unref(p);
-}
-};
-
-using GstSampleUPtr = std::unique_ptr;
-
-struct GstBufferDeleter {
-void operator()(GstBuffer* p)
+template 
+struct GstMiniObjectDeleter {
+void operator()(T* p)
 {
-gst_buffer_unref(p);
+gst_mini_object_unref(GST_MINI_OBJECT_CAST(p));
 }
 };
 
-using GstBufferUPtr = std::unique_ptr;
+template 
+using GstMiniObjectUPtr = std::unique_ptr>;
 
 class GstreamerFrameCapture final : public FrameCapture
 {
@@ -89,7 +73,7 @@ public:
 std::vector get_device_display_info() const override;
 private:
 void free_sample();
-GstElement *get_encoder_plugin(const GstreamerEncoderSettings &settings, 
GstCapsUPtr &sink_caps);
+GstElement *get_encoder_plugin(const GstreamerEncoderSettings &settings, 
GstMiniObjectUPtr &sink_caps);
 GstElement *get_capture_plugin(const GstreamerEncoderSettings &settings);
 void pipeline_init(const GstreamerEncoderSettings &settings);
 Display *const dpy;
@@ -97,7 +81,7 @@ private:
 void xlib_capture();
 #endif
 GstObjectUPtr pipeline, capture, sink;
-GstSampleUPtr sample;
+GstMiniObjectUPtr sample;
 GstMapInfo map = {};
 uint32_t last_width = ~0u, last_height = ~0u;
 uint32_t cur_width = 0, cur_height = 0;
@@ -134,7 +118,7 @@ GstElement *GstreamerFrameCapture::get_capture_plugin(const 
GstreamerEncoderSett
 }
 
 GstElement *GstreamerFrameCapture::get_encoder_plugin(const 
GstreamerEncoderSettings &settings,
-  GstCapsUPtr &sink_caps)
+  
GstMiniObjectUPtr &sink_caps)
 {
 GList *encoders;
 GList *filtered;
@@ -238,7 +222,7 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 if (!convert) {
 throw std::runtime_error("Gstreamer's 'autovideoconvert' element 
cannot be created");
 }
-GstCapsUPtr sink_caps;
+GstMiniObjectUPtr sink_caps;
 GstObjectUPtr encoder(get_encoder_plugin(settings, sink_caps));
 if (!encoder) {
 throw std::runtime_error("Gstreamer's encoder element cannot be 
created");
@@ -260,7 +244,7 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 gst_bin_add(bin, encoder);
 gst_bin_add(bin, sink);
 
-GstCapsUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));
+GstMiniObjectUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));
 link = gst_element_link(capture.get(), convert.get()) &&
gst_element_link_filtered(convert.get(), encoder.get(), caps.get()) 
&&
gst_element_link_filtered(encoder.get(), sink.get(), 
sink_caps.get());
@@ -362,7 +346,7 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Cannot capture from X");
 }
 
-GstBufferUPtr buf(gst_buffer_new_wrapped_full((GstMemoryFlags)0, 
image->data,
+GstMiniObjectUPtr 
buf(gst_buffer_new_wrapped_full((GstMemoryFlags)0, image->data,
   image->height * 
image->bytes_per_line, 0,
   image->height * 
image->bytes_per_line, image,
   free_ximage));
@@ -370,7 +354,7 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
-GstCapsUPtr caps(gst_caps_new_simple("video/x-raw",
+GstMiniObjectUPtr caps(gst_caps_new_simple("video/x-raw",
  "format", G_TYPE_STRING, "BGRx",
  "width", G_TYPE_INT, image->width,
  "height", G_TYPE_INT, image->height,
@@ -378,7 +362,7 @@ void GstreamerFrameCapture::xlib_capture()
  nullptr));
 
 // Push sample
-GstSampleUPtr appsrc_sample(gst_sample_new(buf.get(), caps.get(), nullptr, 
nullptr));
+GstMiniObjectUPtr appsrc_sample(gst_sample_new(buf.get(), 
caps.get(), nullptr, nullptr));
 if (gst_app_src_push_sample(GST_APP_SRC(capture.get()), 
appsrc_sample.get()) != GST_FLOW_OK) {
 throw std::runtime_error("gstramer appsrc element cann

[Spice-devel] [PATCH spice-streaming-agent 2/4] gst-plugin: Allow generation gstreamer dot file

2019-08-01 Thread Snir Sheriber
Set GST_DEBUG_DUMP_DOT_DIR to specify where to place the generated
.dot file
---
 src/gst-plugin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index e9d9364..0a1d041 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -261,7 +261,7 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 }
 
 gst_element_set_state(pipeline.get(), GST_STATE_PLAYING);
-
+GST_DEBUG_BIN_TO_DOT_FILE(bin, GST_DEBUG_GRAPH_SHOW_VERBOSE, 
"gst-plugin-pipeline-debug");
 #if !XLIB_CAPTURE
 int sx, sy, ex, ey;
 g_object_get(capture.get(),
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent 1/4] gst-plugin: Allow ANY memory type to pass from convertor to encoder

2019-08-01 Thread Snir Sheriber
---
 src/gst-plugin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 6415ac0..e9d9364 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -252,7 +252,7 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 gst_bin_add(bin, encoder);
 gst_bin_add(bin, sink);
 
-GstCapsUPtr caps(gst_caps_from_string("video/x-raw"));
+GstCapsUPtr caps(gst_caps_from_string("video/x-raw(ANY)"));
 link = gst_element_link(capture.get(), convert.get()) &&
gst_element_link_filtered(convert.get(), encoder.get(), caps.get()) 
&&
gst_element_link_filtered(encoder.get(), sink.get(), 
sink_caps.get());
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] usb-device-manager: Remove useless cast

2019-07-28 Thread Snir Sheriber

ack

On 7/26/19 1:04 PM, Frediano Ziglio wrote:

spice_usb_device_new is already returning a SpiceUsbDevice pointer.

Signed-off-by: Frediano Ziglio 
---
  src/usb-device-manager.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index a530be9e..544e5687 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -776,7 +776,7 @@ static void 
spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
  return;
  }
  
-device = (SpiceUsbDevice*)spice_usb_device_new(bdev);

+device = spice_usb_device_new(bdev);
  if (!device)
  return;
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk 1/2] spice-widget-egl: Use sizeof instead of hand coded constant

2019-07-22 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 7/22/19 2:25 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  src/spice-widget-egl.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 7bae4e58..7db66082 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -129,7 +129,7 @@ static gboolean spice_egl_init_shaders(SpiceDisplay 
*display, GError **err)
  glLinkProgram(d->egl.prog);
  glGetProgramiv(d->egl.prog, GL_LINK_STATUS, &status);
  if (!status) {
-glGetProgramInfoLog(d->egl.prog, 1000, &len, log);
+glGetProgramInfoLog(d->egl.prog, sizeof(log), &len, log);
  g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
  "error linking shaders: %s", log);
  goto end;

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server 3/3] Use start/end-packet.h headers instead of direct GCC attribute

2019-07-22 Thread Snir Sheriber

Hi,


Here we can also remove some of the packing

Otherwise, ack for the series


On 7/22/19 2:08 PM, Frediano Ziglio wrote:

All other code use these headers.

Signed-off-by: Frediano Ziglio 
---
  server/migration-protocol.h | 32 ++--
  server/reds.c   |  4 +++-
  2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/server/migration-protocol.h b/server/migration-protocol.h
index c8ec56e28..2fc8e0364 100644
--- a/server/migration-protocol.h
+++ b/server/migration-protocol.h
@@ -28,11 +28,13 @@
   * src-server to dst-server migration data messages
   * /
  
+#include 

+
  /* increase the version when the version of any
   * of the migration data messages is increased */
  #define SPICE_MIGRATION_PROTOCOL_VERSION 1
  
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataHeader {

+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataHeader {
  uint32_t magic;
  uint32_t version;
  } SpiceMigrateDataHeader;
@@ -46,7 +48,7 @@ typedef struct __attribute__ ((__packed__)) 
SpiceMigrateDataHeader {
  #define SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION 1
  
  /* Should be the first field of any of the char_devices migration data (see write_data_ptr) */

-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataCharDevice {
+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataCharDevice {
  uint32_t version;
  uint8_t connected;
  uint32_t num_client_tokens;
@@ -64,7 +66,7 @@ typedef struct __attribute__ ((__packed__)) 
SpiceMigrateDataCharDevice {
  #define SPICE_MIGRATE_DATA_SPICEVMC_VERSION 1 /* NOTE: increase version when 
CHAR_DEVICE_VERSION
   is increased */
  #define SPICE_MIGRATE_DATA_SPICEVMC_MAGIC SPICE_MAGIC_CONST("SVMD")
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataSpiceVmc {
+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataSpiceVmc {
  SpiceMigrateDataCharDevice base;
  } SpiceMigrateDataSpiceVmc;
  
@@ -75,7 +77,7 @@ typedef struct __attribute__ ((__packed__)) SpiceMigrateDataSpiceVmc {

  #define SPICE_MIGRATE_DATA_SMARTCARD_VERSION 1 /* NOTE: increase version when 
CHAR_DEVICE_VERSION
is increased */
  #define SPICE_MIGRATE_DATA_SMARTCARD_MAGIC SPICE_MAGIC_CONST("SCMD")
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataSmartcard {
+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataSmartcard {
  SpiceMigrateDataCharDevice base;
  uint8_t reader_added;
  uint32_t read_size; /* partial data read from dev */
@@ -89,11 +91,11 @@ typedef struct __attribute__ ((__packed__)) 
SpiceMigrateDataSmartcard {
   is increased */
  #define SPICE_MIGRATE_DATA_MAIN_MAGIC SPICE_MAGIC_CONST("MNMD")
  
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataMain {

+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataMain {
  SpiceMigrateDataCharDevice agent_base;
  uint8_t client_agent_started; /* for discarding messages */
  
-struct __attribute__ ((__packed__)) {

+struct SPICE_ATTR_PACKED {
  /* partial data read from device. Such data is stored only
   * if the chunk header or the entire msg header haven't yet been read 
completely.
   * Once the headers are read, partial reads of chunks can be sent as
@@ -107,7 +109,7 @@ typedef struct __attribute__ ((__packed__)) 
SpiceMigrateDataMain {
  uint8_t msg_filter_result;
  } agent2client;
  
-struct __attribute__ ((__packed__)) {

+struct SPICE_ATTR_PACKED {
  uint32_t msg_remaining;
  uint8_t msg_filter_result;
  } client2agent;
@@ -128,7 +130,7 @@ typedef struct __attribute__ ((__packed__)) 
SpiceMigrateDataMain {
   * */
  #define MIGRATE_DATA_DISPLAY_MAX_CACHE_CLIENTS 4
  
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataDisplay {

+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataDisplay {
  uint64_t message_serial;
  uint8_t low_bandwidth_setting;
  
@@ -159,28 +161,28 @@ typedef struct __attribute__ ((__packed__)) SpiceMigrateDataDisplay {
  
  } SpiceMigrateDataDisplay;
  
-typedef struct __attribute__ ((__packed__)) SpiceMigrateDataRect {

+typedef struct SPICE_ATTR_PACKED SpiceMigrateDataRect {
  int32_t left;
  int32_t top;
  int32_t right;
  int32_t bottom;
  } SpiceMigrateDataRect;
  
-typedef struct __attribute__ ((__packed__)) MigrateDisplaySurfaceLossless {

+typedef struct SPICE_ATTR_PACKED MigrateDisplaySurfaceLossless {
  uint32_t id;
  } MigrateDisplaySurfaceLossless;
  
-typedef struct __attribute__ ((__packed__)) MigrateDisplaySurfaceLossy {

+typedef struct SPICE_ATTR_PACKED MigrateDisplaySurfaceLossy {
  uint32_t id;
  SpiceMigrateDataRect lossy_rect;
  } MigrateDisplaySurfaceLossy;
  
-typedef struct __attribute__ ((__packed__)) MigrateDisplaySurfacesAtClientLossless {

+typedef struct SPICE_ATTR_PACKED MigrateDi

[Spice-devel] [PATCH v3 spice-streaming-agent] gst-plugin: receive encoder properties as command parameters

2019-07-21 Thread Snir Sheriber
This allows to set plugin key=value properties on run time.
To add encoder plugin property use the following syntax:
-c gst.prop="property=value" -c gst.prop="property2=value2"...
Make sure syntax is accurate and that the property is supported by
the chosen plugin, wrong properties may ignored silently.

Signed-off-by: Snir Sheriber 
---
Changes from v2:
-Mainly c++ style and other minor changes

---
 src/gst-plugin.cpp | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4e802f1..a60afb5 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -35,6 +35,7 @@ struct GstreamerEncoderSettings
 int fps = 25;
 SpiceVideoCodecType codec = SPICE_VIDEO_CODEC_TYPE_H264;
 std::string encoder;
+std::vector> prop_pairs;
 };
 
 template 
@@ -179,11 +180,18 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 }
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
-if (encoder) { // Invalid properties will be ignored silently
-/* x264enc properties */
-gst_util_set_object_arg(G_OBJECT(encoder), "tune", "zerolatency");// 
stillimage, fastdecode, zerolatency
-gst_util_set_object_arg(G_OBJECT(encoder), "bframes", "0");
-gst_util_set_object_arg(G_OBJECT(encoder), "speed-preset", "1");// 
1-ultrafast, 6-med, 9-veryslow
+if (encoder) { // Set encoder properties
+for (const auto &prop : settings.prop_pairs) {
+const auto &name = prop.first;
+const auto &value = prop.second;
+if (!g_object_class_find_property(G_OBJECT_GET_CLASS(encoder), 
name.c_str())) {
+gst_syslog(LOG_WARNING, "'%s' property was not found for this 
encoder", name.c_str());
+continue;
+}
+gst_syslog(LOG_NOTICE, "Trying to set encoder property: '%s = 
%s'", name.c_str(), value.c_str());
+/* Invalid properties will be ignored silently */
+gst_util_set_object_arg(G_OBJECT(encoder), name.c_str(), 
value.c_str());
+}
 }
 gst_plugin_feature_list_free(filtered);
 gst_plugin_feature_list_free(encoders);
@@ -449,6 +457,13 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption 
*options)
 }
 } else if (name == "gst.encoder") {
 settings.encoder = value;
+} else if (name == "gst.prop") {
+size_t pos = value.find('=');
+if (pos == 0 || pos >= value.size() - 1) {
+gst_syslog(LOG_WARNING, "Property input is invalid ('%s' 
Ignored)", value.c_str());
+continue;
+}
+settings.prop_pairs.push_back(make_pair(value.substr(0, pos), 
value.substr(pos + 1)));
 }
 }
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-protocol] start-packet: Correct misleading comment

2019-07-21 Thread Snir Sheriber

Acked-by: Snir Sheriber 

Oh, got it, makes sense!

Thanks


On 7/18/19 6:50 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  spice/start-packed.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/spice/start-packed.h b/spice/start-packed.h
index de0c595..d1d090e 100644
--- a/spice/start-packed.h
+++ b/spice/start-packed.h
@@ -30,8 +30,8 @@
  */
  
  /* Ideally this should all have been macros in a common headers, but

- * its not possible to put pragmas into header files, so we have
- * to use include magic.
+ * its not possible to put pragmas into macros, so we have to use
+ * include magic.
   *
   * Use it like this:
   *

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-protocol 1/2 v2] qxl_dev: Fix alignment for QXLReleaseInfo

2019-07-21 Thread Snir Sheriber


On 7/18/19 6:37 PM, Frediano Ziglio wrote:


On 7/18/19 5:51 PM, Frediano Ziglio wrote:

Hi,


IIRC this was related to some compiler warning, no?

Yes, recent compilers are reporting it, see below.


If it is I'd mentioning it , otherwise, ack.


Just this patch or the entire series?


No, actually i started looking at the second one and wondered why
we are using #include end/start-packed.h

It is mentioned in start-packed.h it's because "its not possible to put
pragmas into header files"

I think instead of

/* Ideally this should all have been macros in a common headers, but
  * its not possible to put pragmas into header files, so we have
  * to use include magic.

should be

/* Ideally this should all have been macros in a common headers, but
  * its not possible to put pragmas into MACROS, so we have
  * to use include magic.

and with C99 you can use _Pragma instead, but for coherence this
method is still fine.


and just after that we put pragma, into this header file.
What am i missing? or the comment is wrong?


Header code is fine, comment is surely misleading.


Snir.


On 7/4/19 4:56 PM, Frediano Ziglio wrote:

Do not declare the structure as aligned.
The start/end-packed.h headers affects structures without
specification only using MingW or Microsoft compilers. For other
platform SPICE_ATTR_PACKED macro should be used.  This way the
definition are the same for all compiler.
This structure is used in a lot of QXL structures which are not
aligned causing to have an aligned structure to be potentially
unaligned.

What about changing this paragraph to:

"This structure is used in a lot of QXL structures which are not
   aligned causing to have an aligned structure to be potentially
   unaligned. Some compilers report a warning for some usage."


Not a big deal but maybe "Some compilers may report a warning"?

Anyway, ack for the change.


Thanks.

Just this patch or also the other one?



Yes, if not pushed yet, I'd also squash, but not necessary
anyway ack for both (squshed or not)

Snir.





As this structure has no holes this change does not make any size
change using any compiler.
The change will only change the alignment from 4/8 to 1.
This could affect structures containing this union however beside
packed structure in qxl_dev.h (which are not affected) there are no
other usages affecting ABI by spice-gtk, Qemu or spice-server.

Signed-off-by: Frediano Ziglio 
---
Changes since v1:
- update commit message
---
spice/qxl_dev.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spice/qxl_dev.h b/spice/qxl_dev.h
index a9cc4f4..659f930 100644
--- a/spice/qxl_dev.h
+++ b/spice/qxl_dev.h
@@ -275,7 +275,7 @@ typedef struct SPICE_ATTR_ALIGNED(4)
SPICE_ATTR_PACKED
QXLRam {

} QXLRam;

-typedef union QXLReleaseInfo {

+typedef union SPICE_ATTR_PACKED QXLReleaseInfo {
uint64_t id;  // in
uint64_t next;// out
} QXLReleaseInfo;

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-protocol 1/2 v2] qxl_dev: Fix alignment for QXLReleaseInfo

2019-07-18 Thread Snir Sheriber


On 7/18/19 5:51 PM, Frediano Ziglio wrote:

Hi,


IIRC this was related to some compiler warning, no?

Yes, recent compilers are reporting it, see below.


If it is I'd mentioning it , otherwise, ack.


Just this patch or the entire series?



No, actually i started looking at the second one and wondered why
we are using #include end/start-packed.h

It is mentioned in start-packed.h it's because "its not possible to put 
pragmas into header files"

and just after that we put pragma, into this header file.
What am i missing? or the comment is wrong?





Snir.


On 7/4/19 4:56 PM, Frediano Ziglio wrote:

Do not declare the structure as aligned.
The start/end-packed.h headers affects structures without
specification only using MingW or Microsoft compilers. For other
platform SPICE_ATTR_PACKED macro should be used.  This way the
definition are the same for all compiler.
This structure is used in a lot of QXL structures which are not
aligned causing to have an aligned structure to be potentially
unaligned.

What about changing this paragraph to:

"This structure is used in a lot of QXL structures which are not
  aligned causing to have an aligned structure to be potentially
  unaligned. Some compilers report a warning for some usage."



Not a big deal but maybe "Some compilers may report a warning"?

Anyway, ack for the change.




As this structure has no holes this change does not make any size
change using any compiler.
The change will only change the alignment from 4/8 to 1.
This could affect structures containing this union however beside
packed structure in qxl_dev.h (which are not affected) there are no
other usages affecting ABI by spice-gtk, Qemu or spice-server.

Signed-off-by: Frediano Ziglio 
---
Changes since v1:
- update commit message
---
   spice/qxl_dev.h | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spice/qxl_dev.h b/spice/qxl_dev.h
index a9cc4f4..659f930 100644
--- a/spice/qxl_dev.h
+++ b/spice/qxl_dev.h
@@ -275,7 +275,7 @@ typedef struct SPICE_ATTR_ALIGNED(4) SPICE_ATTR_PACKED
QXLRam {
   
   } QXLRam;
   
-typedef union QXLReleaseInfo {

+typedef union SPICE_ATTR_PACKED QXLReleaseInfo {
   uint64_t id;  // in
   uint64_t next;// out
   } QXLReleaseInfo;

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-protocol 1/2 v2] qxl_dev: Fix alignment for QXLReleaseInfo

2019-07-18 Thread Snir Sheriber

Hi,


IIRC this was related to some compiler warning, no?
If it is I'd mentioning it , otherwise, ack.

Snir.


On 7/4/19 4:56 PM, Frediano Ziglio wrote:

Do not declare the structure as aligned.
The start/end-packed.h headers affects structures without
specification only using MingW or Microsoft compilers. For other
platform SPICE_ATTR_PACKED macro should be used.  This way the
definition are the same for all compiler.
This structure is used in a lot of QXL structures which are not
aligned causing to have an aligned structure to be potentially
unaligned.
As this structure has no holes this change does not make any size
change using any compiler.
The change will only change the alignment from 4/8 to 1.
This could affect structures containing this union however beside
packed structure in qxl_dev.h (which are not affected) there are no
other usages affecting ABI by spice-gtk, Qemu or spice-server.

Signed-off-by: Frediano Ziglio 
---
Changes since v1:
- update commit message
---
  spice/qxl_dev.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spice/qxl_dev.h b/spice/qxl_dev.h
index a9cc4f4..659f930 100644
--- a/spice/qxl_dev.h
+++ b/spice/qxl_dev.h
@@ -275,7 +275,7 @@ typedef struct SPICE_ATTR_ALIGNED(4) SPICE_ATTR_PACKED 
QXLRam {
  
  } QXLRam;
  
-typedef union QXLReleaseInfo {

+typedef union SPICE_ATTR_PACKED QXLReleaseInfo {
  uint64_t id;  // in
  uint64_t next;// out
  } QXLReleaseInfo;

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH v2 spice-streaming-agent] gst-plugin: receive encoder properties as command parameters

2019-07-17 Thread Snir Sheriber
From: test 

This allows to set plugin key=value properties on run time.
To add encoder plugin property use the following syntax:
-c gst.prop="property=value" -c gst.prop="property2=value2"...
Make sure syntax is accurate and that the property is supported by
the chosen plugin, wrong properties may ignored silently.

Signed-off-by: Snir Sheriber 
---

Difference from v1:
-Variables naming
-Using vector of pairs
-Add warnings for wrong input
-Set propeties after log msg
-Fix commit msg

*There is only basic input validation, assuming the user is
 accurate with the properties he sets.
 Currently the code checks property name exists for the encoder
 object, i had a version that checks also the value matches the
 property type but it seems to be over-coding for this purpose.
 
---
 src/gst-plugin.cpp | 28 +++-
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4e802f1..3270cce 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -35,6 +35,7 @@ struct GstreamerEncoderSettings
 int fps = 25;
 SpiceVideoCodecType codec = SPICE_VIDEO_CODEC_TYPE_H264;
 std::string encoder;
+std::vector> prop_pairs;
 };
 
 template 
@@ -179,11 +180,18 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 }
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
-if (encoder) { // Invalid properties will be ignored silently
-/* x264enc properties */
-gst_util_set_object_arg(G_OBJECT(encoder), "tune", "zerolatency");// 
stillimage, fastdecode, zerolatency
-gst_util_set_object_arg(G_OBJECT(encoder), "bframes", "0");
-gst_util_set_object_arg(G_OBJECT(encoder), "speed-preset", "1");// 
1-ultrafast, 6-med, 9-veryslow
+if (encoder) { // Set encoder properties
+for (int i = 0; i < settings.prop_pairs.size(); i++) {
+const char *prop_name = settings.prop_pairs[i].first.c_str();
+if (!g_object_class_find_property(G_OBJECT_GET_CLASS(encoder), 
prop_name)) {
+gst_syslog(LOG_WARNING, "'%s' property was not found for this 
encoder", prop_name);
+continue;
+}
+const char *prop_val = settings.prop_pairs[i].second.c_str();
+gst_syslog(LOG_NOTICE, "Trying to set encoder property: '%s = 
%s'", prop_name, prop_val);
+/* Invalid properties will be ignored silently */
+gst_util_set_object_arg(G_OBJECT(encoder), prop_name, prop_val);
+}
 }
 gst_plugin_feature_list_free(filtered);
 gst_plugin_feature_list_free(encoders);
@@ -449,6 +457,16 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption 
*options)
 }
 } else if (name == "gst.encoder") {
 settings.encoder = value;
+} else if (name == "gst.prop") {
+std::string prop_name, prop_val;
+size_t pos = value.find('=');
+if (!pos || pos >= value.size() - 1) {
+gst_syslog(LOG_WARNING, "Property input is invalid ('%s' 
Ignored)", value.c_str());
+continue;
+}
+prop_name = value.substr(0, pos);
+prop_val = value.substr(pos + 1);
+settings.prop_pairs.push_back(make_pair(prop_name, prop_val));
 }
 }
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-streaming-agent] gst-plugin: receive encoder properties as command parameters

2019-07-17 Thread Snir Sheriber

Hi,


On 7/16/19 2:35 PM, Frediano Ziglio wrote:

This allows to set plugin key=value properties on run time.
To add encoder plugin property use the following syntax:
-gst.prop="key=value"
Make sure syntax is accurate and that the property is supported by
the chosen plugin, wrong/invalid properties will be ignored silently.
Specific encoder available properties can be viewed by:
gst-inspect-1.0 
---
* This patch useful for encoders tuning and testing (later we can introduce
   fixed encoders setups), hence not checking for validity of input.
* I dropped sstream in previous patch but i found it useful here and added it
   again, alternative suggestions are welcome


Nothing wrong against its usage, but see below


---
  src/gst-plugin.cpp | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4e802f1..0d8773d 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -6,6 +6,7 @@
  
  #include 

  #include 
+#include 
  #include 
  #include 
  #include 
@@ -35,6 +36,7 @@ struct GstreamerEncoderSettings
  int fps = 25;
  SpiceVideoCodecType codec = SPICE_VIDEO_CODEC_TYPE_H264;
  std::string encoder;
+std::vector prop_strings;

Why not a std::map?
It looks a bit unnatural, it's not a vector, even elements are property names,
odd elements are values.



These are {key,value} pairs, which are also passed as pairs to gstreamer,
accessing them is by iterating over all pairs.
Since extraction of values through their key is not required i'd suggest 
to use

vector of pairs instead.



std::map will avoid duplication of properties with same name (which look good)
but you would lose the order (which could be an issue... or not?)



Yes, losing the order is not an issue.



I'll send a new version, fixing the other stuff as well.

Thanks!





  };
  
  template 

@@ -180,10 +182,15 @@ GstElement
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
  
  encoder = factory ? gst_element_factory_create(factory, "encoder") :

  nullptr;
  if (encoder) { // Invalid properties will be ignored silently
-/* x264enc properties */
-gst_util_set_object_arg(G_OBJECT(encoder), "tune", "zerolatency");//
stillimage, fastdecode, zerolatency
-gst_util_set_object_arg(G_OBJECT(encoder), "bframes", "0");
-gst_util_set_object_arg(G_OBJECT(encoder), "speed-preset", "1");//
1-ultrafast, 6-med, 9-veryslow
+const char *key;
+const char *val;
+for (int i = 1; i < settings.prop_strings.size(); i += 2) {
+key = settings.prop_strings[i-1].c_str();
+val = settings.prop_strings[i].c_str();

I would personally declare and initialize, more C++ style


+gst_util_set_object_arg(G_OBJECT(encoder), key, val);
+gst_syslog(LOG_NOTICE, "Trying to set encoder property: '%s =
%s'", key, val);

"Trying" looks like you will doing, but after IMHO should be "Tried to".


+}
+
  }
  gst_plugin_feature_list_free(filtered);
  gst_plugin_feature_list_free(encoders);
@@ -449,6 +456,12 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption
*options)
  }
  } else if (name == "gst.encoder") {
  settings.encoder = value;
+} else if (name == "gst.prop") {
+std::stringstream ss(value);
+std::string item;
+while (std::getline(ss, item, '=')) {

This has some problems:
- if value contains multiple "=" this will be split and part of values will
   become property names;
- if value doesn't contain any "=" the entire value will be considered as
   the property name of following arguments.
In Python that would probably be a string.split('=', 1).
Maybe a combination of string.find and string.substr would avoid these
issues.
I could also potentially pass something like (shell syntax)


$ program ... -c "gst.prop=name=value
next line=2"


(property value with "=" and new line embedded).


+   settings.prop_strings.push_back(item);
+}
  }
  }
  }

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent] gst-plugin: receive encoder properties as command parameters

2019-07-16 Thread Snir Sheriber
This allows to set plugin key=value properties on run time.
To add encoder plugin property use the following syntax:
-gst.prop="key=value"
Make sure syntax is accurate and that the property is supported by
the chosen plugin, wrong/invalid properties will be ignored silently.
Specific encoder available properties can be viewed by:
gst-inspect-1.0 
---
* This patch useful for encoders tuning and testing (later we can introduce
  fixed encoders setups), hence not checking for validity of input.
* I dropped sstream in previous patch but i found it useful here and added it
  again, alternative suggestions are welcome

---
 src/gst-plugin.cpp | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 4e802f1..0d8773d 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -35,6 +36,7 @@ struct GstreamerEncoderSettings
 int fps = 25;
 SpiceVideoCodecType codec = SPICE_VIDEO_CODEC_TYPE_H264;
 std::string encoder;
+std::vector prop_strings;
 };
 
 template 
@@ -180,10 +182,15 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
 if (encoder) { // Invalid properties will be ignored silently
-/* x264enc properties */
-gst_util_set_object_arg(G_OBJECT(encoder), "tune", "zerolatency");// 
stillimage, fastdecode, zerolatency
-gst_util_set_object_arg(G_OBJECT(encoder), "bframes", "0");
-gst_util_set_object_arg(G_OBJECT(encoder), "speed-preset", "1");// 
1-ultrafast, 6-med, 9-veryslow
+const char *key;
+const char *val;
+for (int i = 1; i < settings.prop_strings.size(); i += 2) {
+key = settings.prop_strings[i-1].c_str();
+val = settings.prop_strings[i].c_str();
+gst_util_set_object_arg(G_OBJECT(encoder), key, val);
+gst_syslog(LOG_NOTICE, "Trying to set encoder property: '%s = 
%s'", key, val);
+}
+
 }
 gst_plugin_feature_list_free(filtered);
 gst_plugin_feature_list_free(encoders);
@@ -449,6 +456,12 @@ void GstreamerPlugin::ParseOptions(const ConfigureOption 
*options)
 }
 } else if (name == "gst.encoder") {
 settings.encoder = value;
+} else if (name == "gst.prop") {
+std::stringstream ss(value);
+std::string item;
+while (std::getline(ss, item, '=')) {
+   settings.prop_strings.push_back(item);
+}
 }
 }
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server v2] red-qxl: Better encapsulation of device display information

2019-07-08 Thread Snir Sheriber

Acked-by: Snir Sheriber 


On 7/7/19 7:35 PM, Frediano Ziglio wrote:

Do not expose multiple functions to fetch different parts of
internal structure.

Signed-off-by: Frediano Ziglio 
---
  server/red-qxl.c | 34 +-
  server/red-qxl.h |  4 +---
  server/reds.c| 19 +--
  3 files changed, 23 insertions(+), 34 deletions(-)

Changes since v1:
- commit message fixes
- add new line after variable declarations
- add qxl_state variable

diff --git a/server/red-qxl.c b/server/red-qxl.c
index d40d3970d..03348270f 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -809,22 +809,30 @@ void spice_qxl_set_device_info(QXLInstance *instance,
  reds_send_device_display_info(red_qxl_get_server(instance->st));
  }
  
-const char* red_qxl_get_device_address(const QXLInstance *qxl)

+uint32_t red_qxl_marshall_device_display_info(const QXLInstance *qxl, 
SpiceMarshaller *m)
  {
  const QXLState *qxl_state = qxl->st;
-return qxl_state->device_address;
-}
-
-const uint32_t* red_qxl_get_device_display_ids(const QXLInstance *qxl)
-{
-const QXLState *qxl_state = qxl->st;
-return qxl_state->device_display_ids;
-}
+uint32_t device_count = 0;
+const char *const device_address = qxl_state->device_address;
+const size_t device_address_len = strlen(device_address) + 1;
  
-size_t red_qxl_get_monitors_count(const QXLInstance *qxl)

-{
-const QXLState *qxl_state = qxl->st;
-return qxl_state->monitors_count;
+if (device_address_len == 1) {
+return 0;
+}
+for (size_t i = 0; i < qxl_state->monitors_count; ++i) {
+spice_marshaller_add_uint32(m, qxl->id);
+spice_marshaller_add_uint32(m, i);
+spice_marshaller_add_uint32(m, qxl_state->device_display_ids[i]);
+spice_marshaller_add_uint32(m, device_address_len);
+spice_marshaller_add(m, (void*) device_address, device_address_len);
+++device_count;
+
+g_debug("   (qxl)channel_id: %u monitor_id: %zu, device_address: %s, 
"
+"device_display_id: %u",
+qxl->id, i, device_address,
+qxl_state->device_display_ids[i]);
+}
+return device_count;
  }
  
  void red_qxl_init(RedsState *reds, QXLInstance *qxl)

diff --git a/server/red-qxl.h b/server/red-qxl.h
index 947539482..5bb254adb 100644
--- a/server/red-qxl.h
+++ b/server/red-qxl.h
@@ -40,9 +40,7 @@ void red_qxl_put_gl_scanout(QXLInstance *qxl, 
SpiceMsgDisplayGlScanoutUnix *scan
  void red_qxl_gl_draw_async_complete(QXLInstance *qxl);
  int red_qxl_check_qxl_version(QXLInstance *qxl, int major, int minor);
  SpiceServer* red_qxl_get_server(QXLState *qxl);
-const char* red_qxl_get_device_address(const QXLInstance *qxl);
-const uint32_t* red_qxl_get_device_display_ids(const QXLInstance *qxl);
-size_t red_qxl_get_monitors_count(const QXLInstance *qxl);
+uint32_t red_qxl_marshall_device_display_info(const QXLInstance *qxl, 
SpiceMarshaller *m);
  
  /* Wrappers around QXLInterface vfuncs */

  void red_qxl_get_init_info(QXLInstance *qxl, QXLDevInitInfo *info);
diff --git a/server/reds.c b/server/reds.c
index 7783ab0b4..817fdd423 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -920,24 +920,7 @@ void reds_marshall_device_display_info(RedsState *reds, 
SpiceMarshaller *m)
  
  // add the qxl devices to the message

  FOREACH_QXL_INSTANCE(reds, qxl) {
-const char *const device_address = red_qxl_get_device_address(qxl);
-const size_t device_address_len = strlen(device_address) + 1;
-if (device_address_len == 1) {
-continue;
-}
-for (size_t i = 0; i < red_qxl_get_monitors_count(qxl); ++i) {
-spice_marshaller_add_uint32(m, qxl->id);
-spice_marshaller_add_uint32(m, i);
-spice_marshaller_add_uint32(m, 
red_qxl_get_device_display_ids(qxl)[i]);
-spice_marshaller_add_uint32(m, device_address_len);
-spice_marshaller_add(m, (void*) device_address, 
device_address_len);
-++device_count;
-
-g_debug("   (qxl)channel_id: %u monitor_id: %zu, device_address: 
%s, "
-"device_display_id: %u",
-qxl->id, i, device_address,
-red_qxl_get_device_display_ids(qxl)[i]);
-}
+device_count += red_qxl_marshall_device_display_info(qxl, m);
  }
  
  // add the stream devices to the message

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server v2] test-codecs-parsing: On bad codec string spice_server_set_video_codecs can fail

2019-07-07 Thread Snir Sheriber

Acked-by: Snir Sheriber 
The 0 result means success however the function (correctly) could
report a failure if the string is incorrect.
This fixes the test after commit b4150de3cd0e56d4ce43a99ef5c3c5f5cbdfc4a3
("spice_server_set_video_codecs: fail when no codec can be installed").

Signed-off-by: Frediano Ziglio 
---
  server/tests/test-codecs-parsing.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Changes since v1:
- check always error setting codecs.

diff --git a/server/tests/test-codecs-parsing.c 
b/server/tests/test-codecs-parsing.c
index 7998501c9..0037c058f 100644
--- a/server/tests/test-codecs-parsing.c
+++ b/server/tests/test-codecs-parsing.c
@@ -140,7 +140,7 @@ static void codecs_bad(void)
  g_test_expect_message(G_LOG_DOMAIN, test_cases[i].log_level, 
test_cases[i].error_message);
  if (test_cases[i].default_err_message)
  g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Failed to 
set video codecs*");
-g_assert_cmpint(spice_server_set_video_codecs(server, 
test_cases[i].codecs), ==, 0);
+g_assert_cmpint(spice_server_set_video_codecs(server, 
test_cases[i].codecs), !=, 0);
  g_test_assert_expected_messages();
  }
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] test-codecs-parsing: On bad codec string spice_server_set_video_codecs can fail

2019-07-07 Thread Snir Sheriber

Hi,

On 7/5/19 4:09 PM, Frediano Ziglio wrote:

The 0 result means success however the function (correctly) could
report a failure if the string is incorrect.
This fixes the test after commit b4150de3cd0e56d4ce43a99ef5c3c5f5cbdfc4a3
("spice_server_set_video_codecs: fail when no codec can be installed").

Signed-off-by: Frediano Ziglio 
---
  server/tests/test-codecs-parsing.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/tests/test-codecs-parsing.c 
b/server/tests/test-codecs-parsing.c
index 7998501c9..08d83cc2b 100644
--- a/server/tests/test-codecs-parsing.c
+++ b/server/tests/test-codecs-parsing.c
@@ -140,7 +140,7 @@ static void codecs_bad(void)
  g_test_expect_message(G_LOG_DOMAIN, test_cases[i].log_level, 
test_cases[i].error_message);
  if (test_cases[i].default_err_message)
  g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Failed to 
set video codecs*");
-g_assert_cmpint(spice_server_set_video_codecs(server, 
test_cases[i].codecs), ==, 0);
+spice_server_set_video_codecs(server, test_cases[i].codecs);



Can't we assert for  -1 now?

Snir.


  g_test_assert_expected_messages();
  }
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] red-qxl: Better encapsulation of device display information

2019-07-07 Thread Snir Sheriber

Hi,

On 7/5/19 6:47 PM, Frediano Ziglio wrote:

Do not expose multiple function to fetch different part of
internal structures.


shouldn't be "Do not expose multiple functions to fetch different parts of
internal structure." ?




Signed-off-by: Frediano Ziglio 
---
  server/red-qxl.c | 36 +---
  server/red-qxl.h |  4 +---
  server/reds.c| 19 +--
  3 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/server/red-qxl.c b/server/red-qxl.c
index d40d3970d..843da7dfe 100644
--- a/server/red-qxl.c
+++ b/server/red-qxl.c
@@ -809,22 +809,28 @@ void spice_qxl_set_device_info(QXLInstance *instance,
  reds_send_device_display_info(red_qxl_get_server(instance->st));
  }
  
-const char* red_qxl_get_device_address(const QXLInstance *qxl)

+uint32_t red_qxl_marshall_device_display_info(const QXLInstance *qxl, 
SpiceMarshaller *m)
  {
-const QXLState *qxl_state = qxl->st;
-return qxl_state->device_address;
-}
-
-const uint32_t* red_qxl_get_device_display_ids(const QXLInstance *qxl)
-{
-const QXLState *qxl_state = qxl->st;
-return qxl_state->device_display_ids;
-}
-
-size_t red_qxl_get_monitors_count(const QXLInstance *qxl)
-{
-const QXLState *qxl_state = qxl->st;
-return qxl_state->monitors_count;
+uint32_t device_count = 0;
+const char *const device_address = qxl->st->device_address;


new line maybe

Other than that it makes sense and fine with me (a bit uncomfortable 
with doing marshaling in red-qxl though)


Snir.


+const size_t device_address_len = strlen(device_address) + 1;
+if (device_address_len == 1) {
+return 0;
+}
+for (size_t i = 0; i < qxl->st->monitors_count; ++i) {
+spice_marshaller_add_uint32(m, qxl->id);
+spice_marshaller_add_uint32(m, i);
+spice_marshaller_add_uint32(m, qxl->st->device_display_ids[i]);
+spice_marshaller_add_uint32(m, device_address_len);
+spice_marshaller_add(m, (void*) device_address, device_address_len);
+++device_count;
+
+g_debug("   (qxl)channel_id: %u monitor_id: %zu, device_address: %s, 
"
+"device_display_id: %u",
+qxl->id, i, device_address,
+qxl->st->device_display_ids[i]);
+}
+return device_count;
  }
  
  void red_qxl_init(RedsState *reds, QXLInstance *qxl)

diff --git a/server/red-qxl.h b/server/red-qxl.h
index 947539482..5bb254adb 100644
--- a/server/red-qxl.h
+++ b/server/red-qxl.h
@@ -40,9 +40,7 @@ void red_qxl_put_gl_scanout(QXLInstance *qxl, 
SpiceMsgDisplayGlScanoutUnix *scan
  void red_qxl_gl_draw_async_complete(QXLInstance *qxl);
  int red_qxl_check_qxl_version(QXLInstance *qxl, int major, int minor);
  SpiceServer* red_qxl_get_server(QXLState *qxl);
-const char* red_qxl_get_device_address(const QXLInstance *qxl);
-const uint32_t* red_qxl_get_device_display_ids(const QXLInstance *qxl);
-size_t red_qxl_get_monitors_count(const QXLInstance *qxl);
+uint32_t red_qxl_marshall_device_display_info(const QXLInstance *qxl, 
SpiceMarshaller *m);
  
  /* Wrappers around QXLInterface vfuncs */

  void red_qxl_get_init_info(QXLInstance *qxl, QXLDevInitInfo *info);
diff --git a/server/reds.c b/server/reds.c
index 7783ab0b4..817fdd423 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -920,24 +920,7 @@ void reds_marshall_device_display_info(RedsState *reds, 
SpiceMarshaller *m)
  
  // add the qxl devices to the message

  FOREACH_QXL_INSTANCE(reds, qxl) {
-const char *const device_address = red_qxl_get_device_address(qxl);
-const size_t device_address_len = strlen(device_address) + 1;
-if (device_address_len == 1) {
-continue;
-}
-for (size_t i = 0; i < red_qxl_get_monitors_count(qxl); ++i) {
-spice_marshaller_add_uint32(m, qxl->id);
-spice_marshaller_add_uint32(m, i);
-spice_marshaller_add_uint32(m, 
red_qxl_get_device_display_ids(qxl)[i]);
-spice_marshaller_add_uint32(m, device_address_len);
-spice_marshaller_add(m, (void*) device_address, 
device_address_len);
-++device_count;
-
-g_debug("   (qxl)channel_id: %u monitor_id: %zu, device_address: 
%s, "
-"device_display_id: %u",
-qxl->id, i, device_address,
-red_qxl_get_device_display_ids(qxl)[i]);
-}
+device_count += red_qxl_marshall_device_display_info(qxl, m);
  }
  
  // add the stream devices to the message

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] smartcard-channel-client: Fix some typos in a comment

2019-07-02 Thread Snir Sheriber

ack

Acked-by: Snir Sheriber 

On 6/2/19 8:53 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  server/smartcard-channel-client.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/smartcard-channel-client.c 
b/server/smartcard-channel-client.c
index e22b39adf..e462401e0 100644
--- a/server/smartcard-channel-client.c
+++ b/server/smartcard-channel-client.c
@@ -123,9 +123,9 @@ smartcard_channel_client_alloc_msg_rcv_buf(RedChannelClient 
*rcc,
  SmartCardChannelClient *scc = SMARTCARD_CHANNEL_CLIENT(rcc);
  RedClient *client = red_channel_client_get_client(rcc);
  
-/* todo: only one reader is actually supported. When we fix the code to support

- * multiple readers, we will porbably associate different devices to
- * differenc channels */
+/* TODO: only one reader is actually supported. When we fix the code to 
support
+ * multiple readers, we will probably associate different devices to
+ * different channels */
  if (!scc->priv->smartcard) {
  scc->priv->msg_in_write_buf = FALSE;
  return g_malloc(size);

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] red-parse-qxl: Reset mask attributes if brush image is missing

2019-07-02 Thread Snir Sheriber

Hi,

On 6/2/19 8:53 PM, Frediano Ziglio wrote:

The attributes in this case are not used to apply the mask.
Doing so avoid sending garbage from the guest which usually
don't initialise the memory in case the mask is missing.
Guest should have cleared these bytes by its own however doing so
on the server fixes the problem too. Considering that these
command should not appears in newer OSes it's surely not a hot path
code.
These garbage came from video memory of the guest so they don't
contain sensitive data.

This fixes https://gitlab.freedesktop.org/spice/spice-server/issues/25.

Signed-off-by: Frediano Ziglio 
---
  server/red-parse-qxl.c | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
index afae94316..a4ac6a473 100644
--- a/server/red-parse-qxl.c
+++ b/server/red-parse-qxl.c
@@ -626,9 +626,15 @@ static void red_put_brush(SpiceBrush *red)
  static void red_get_qmask_ptr(RedMemSlotInfo *slots, int group_id,
SpiceQMask *red, QXLQMask *qxl, uint32_t flags)
  {
-red->flags  = qxl->flags;
-red_get_point_ptr(&red->pos, &qxl->pos);
  red->bitmap = red_get_image(slots, group_id, qxl->bitmap, flags, true);
+if (red->bitmap) {
+red->flags  = qxl->flags;
+red_get_point_ptr(&red->pos, &qxl->pos);
+} else {
+red->flags  = 0;
+red->pos.x = 0;
+red->pos.y = 0;



Not really impotent but maybe we an also consider a red_set_point_ptr 
function


Anyways looks fine to me.

Snir.



+}
  }
  
  static void red_put_qmask(SpiceQMask *red)

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice] manual: Typo at `Folder sharing` section

2019-07-02 Thread Snir Sheriber
Reported here:
https://gitlab.freedesktop.org/spice/spice-space-pages/issues/1
---
Following to this fix website manual will be automatically generated
---
 docs/manual/manual.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/manual/manual.txt b/docs/manual/manual.txt
index 9de3c470..ddb7c0f2 100644
--- a/docs/manual/manual.txt
+++ b/docs/manual/manual.txt
@@ -905,7 +905,7 @@ The Spice client can share a folder with the remote guest. 
By default folder
 sharing is disabled. Use the remote-viewer "File" -> "Preferences" menu
 to enable it. The default shared directory is the XDG Public Share directory
 (ie '~/Public' if you use a regular system). You may specify a different folder
-with `--spice-share-dir` client option.
+with `--spice-shared-dir` client option.
 
 Configuration
 -
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH v3 spice-streaming-agent] drop sstream and use dedicated functions instead

2019-07-01 Thread Snir Sheriber
Instead of manipulating a string and convert it to caps just
use dedicated functions instead

Signed-off-by: Snir Sheriber 
---
Changes from v2:
 -use g_free as a deleter
 (exactly 100 characters width)

---
 src/gst-plugin.cpp | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index cb310d0..444a908 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -8,7 +8,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -132,34 +131,35 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 GList *filtered;
 GstElement *encoder;
 GstElementFactory *factory = nullptr;
-std::stringstream caps_ss;
 
 switch (settings.codec) {
 case SPICE_VIDEO_CODEC_TYPE_H264:
-caps_ss << "video/x-h264" << ",stream-format=(string)byte-stream";
+sink_caps.reset(gst_caps_new_simple("video/x-h264",
+"stream-format", G_TYPE_STRING, 
"byte-stream",
+NULL));
 break;
 case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-caps_ss << "image/jpeg";
+sink_caps.reset(gst_caps_new_empty_simple("image/jpeg"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP8:
-caps_ss << "video/x-vp8";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp8"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP9:
-caps_ss << "video/x-vp9";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp9"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_H265:
-caps_ss << "video/x-h265";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-h265"));
 break;
 default : /* Should not happen - just to avoid compiler's complaint */
 throw std::logic_error("Unknown codec");
 }
-caps_ss << ",framerate=" << settings.fps << "/1";
+gst_caps_set_simple(sink_caps.get(), "framerate", GST_TYPE_FRACTION, 
settings.fps, 1, nullptr);
+std::unique_ptr 
caps_str(gst_caps_to_string(sink_caps.get()), g_free);
 
 encoders = 
gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER, 
GST_RANK_NONE);
-sink_caps.reset(gst_caps_from_string(caps_ss.str().c_str()));
 filtered = gst_element_factory_list_filter(encoders, sink_caps.get(), 
GST_PAD_SRC, false);
 if (filtered) {
-gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_ss.str().c_str());
+gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_str.get());
 for (GList *l = filtered; l != nullptr; l = l->next) {
 if (!factory && 
!settings.encoder.compare(GST_ELEMENT_NAME(l->data))) {
 factory = (GstElementFactory*)l->data;
@@ -169,13 +169,13 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 if (!factory && !settings.encoder.empty()) {
 gst_syslog(LOG_WARNING,
"Specified encoder named '%s' cannot produce '%s' 
stream, make sure matching gst.codec is specified and plugin's availability",
-   settings.encoder.c_str(), caps_ss.str().c_str());
+   settings.encoder.c_str(), caps_str.get());
 }
 factory = factory ? factory : (GstElementFactory*)filtered->data;
 gst_syslog(LOG_NOTICE, "'%s' encoder plugin is used", 
GST_ELEMENT_NAME(factory));
 
 } else {
-gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_ss.str().c_str());
+gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_str.get());
 }
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
@@ -351,10 +351,12 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
-std::stringstream ss;
-
-ss << "video/x-raw,format=BGRx,width=" << image->width << ",height=" << 
image->height << ",framerate=" << settings.fps << "/1";
-GstCapsUPtr caps(gst_caps_from_string(ss.str().c_str()));
+GstCapsUPtr caps(gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "BGRx",
+ "width", G_TYPE_INT, image->width,
+ "height", G_TYPE_INT, image->height,
+ "framerate", GST_TYPE_FRACTION, 
settings.fps, 1,
+ NULL));
 
 // Push sample
 GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, 
nullptr));
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] Replace some missing "latency" terms

2019-07-01 Thread Snir Sheriber

Ack for both

On 6/28/19 10:46 AM, Frediano Ziglio wrote:

ping


This follows up commit 887aedff41bdb89845e7cb349454a8dcbb515db4
"The video latency is in fact a margin".

Signed-off-by: Frediano Ziglio 
---
  src/channel-display-priv.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 495df7ac..16c12c6e 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -63,12 +63,12 @@ struct VideoDecoder {
   *
   * @decoder:   The video decoder.
   * @frame: The compressed Spice frame.
- * @latency:   How long in milliseconds until the frame should be
+ * @margin:How long in milliseconds until the frame should be
   * displayed. Negative values mean the frame is late.
   * @return:False if the decoder can no longer decode frames,
   * True otherwise.
   */
-gboolean (*queue_frame)(VideoDecoder *video_decoder, SpiceFrame *frame,
int latency);
+gboolean (*queue_frame)(VideoDecoder *video_decoder, SpiceFrame *frame,
int margin);
  
  /* The format of the encoded video. */

  int codec_type;

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH v2 spice-streaming-agent 1/2] drop sstream and use dedicated functions instead

2019-06-27 Thread Snir Sheriber

Hi,


On 6/27/19 5:12 PM, Frediano Ziglio wrote:

Instead of manipulating a string and convert it to caps just
use dedicated functions instead

Signed-off-by: Snir Sheriber 
---
Changes:
-commit log
-Suggesting uniqptr for caps_str
--
  src/gst-plugin.cpp | 34 ++
  1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..0dd7796 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -8,7 +8,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
@@ -132,34 +131,35 @@ GstElement
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
  GList *filtered;
  GstElement *encoder;
  GstElementFactory *factory = nullptr;
-std::stringstream caps_ss;
  
  switch (settings.codec) {

  case SPICE_VIDEO_CODEC_TYPE_H264:
-caps_ss << "video/x-h264" << ",stream-format=(string)byte-stream";
+sink_caps.reset(gst_caps_new_simple("video/x-h264",
+"stream-format", G_TYPE_STRING,
"byte-stream",
+NULL));
  break;
  case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-caps_ss << "image/jpeg";
+sink_caps.reset(gst_caps_new_empty_simple("image/jpeg"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_VP8:
-caps_ss << "video/x-vp8";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp8"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_VP9:
-caps_ss << "video/x-vp9";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp9"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_H265:
-caps_ss << "video/x-h265";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-h265"));
  break;
  default : /* Should not happen - just to avoid compiler's complaint */
  throw std::logic_error("Unknown codec");
  }
-caps_ss << ",framerate=" << settings.fps << "/1";
+gst_caps_set_simple(sink_caps.get(), "framerate", GST_TYPE_FRACTION,
settings.fps, 1, nullptr);
+std::unique_ptr caps_str(gst_caps_to_string(sink_caps.get()));
  

Idea it's fine. This however will call ::operator new which it's not what
you want. In the same file there are different deleters like


struct GstSampleDeleter {
 void operator()(GstSample* p)
 {
 gst_sample_unref(p);
 }
};

using GstSampleUPtr = std::unique_ptr;


you can base your one. Glibmm uses an utility (see
https://gitlab.gnome.org/GNOME/glibmm/blob/b92ef23e38f9863ebe4704a916e3322eea2f1f2c/glib/glibmm/utility.h)
but potentially each smart pointer will contain a pointer to g_free
(and it's limited to g_free like a single deleter).



How about this oneliner instead?

std::unique_ptr 
caps_str(gst_caps_to_string(sink_caps.get()), &g_free);


Snir.



  encoders =
  
gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER,
  GST_RANK_NONE);
-sink_caps.reset(gst_caps_from_string(caps_ss.str().c_str()));
  filtered = gst_element_factory_list_filter(encoders, sink_caps.get(),
  GST_PAD_SRC, false);
  if (filtered) {
-gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can
produce a '%s' stream", caps_ss.str().c_str());
+gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can
produce a '%s' stream", caps_str.get());
  for (GList *l = filtered; l != nullptr; l = l->next) {
  if (!factory &&
  !settings.encoder.compare(GST_ELEMENT_NAME(l->data))) {
  factory = (GstElementFactory*)l->data;
@@ -169,13 +169,13 @@ GstElement
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
  if (!factory && !settings.encoder.empty()) {
  gst_syslog(LOG_WARNING,
 "Specified encoder named '%s' cannot produce '%s'
 stream, make sure matching gst.codec is specified
 and plugin's availability",
-   settings.encoder.c_str(), caps_ss.str().c_str());
+   settings.encoder.c_str(), caps_str.get());
  }
  factory = factory ? factory : (GstElementFactory*)filtered->data;
  gst_syslog(LOG_NOTICE, "'%s' encoder plugin is used",
  GST_ELEMENT_NAME(factory));
  
  } else {

-gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'",
caps_ss.str().c_str());
+gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'",
caps_str.get());
  }
  

[Spice-devel] [PATCH v2 spice-streaming-agent 1/2] drop sstream and use dedicated functions instead

2019-06-27 Thread Snir Sheriber
Instead of manipulating a string and convert it to caps just
use dedicated functions instead

Signed-off-by: Snir Sheriber 
---
Changes:
-commit log
-Suggesting uniqptr for caps_str
--
 src/gst-plugin.cpp | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..0dd7796 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -8,7 +8,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -132,34 +131,35 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 GList *filtered;
 GstElement *encoder;
 GstElementFactory *factory = nullptr;
-std::stringstream caps_ss;
 
 switch (settings.codec) {
 case SPICE_VIDEO_CODEC_TYPE_H264:
-caps_ss << "video/x-h264" << ",stream-format=(string)byte-stream";
+sink_caps.reset(gst_caps_new_simple("video/x-h264",
+"stream-format", G_TYPE_STRING, 
"byte-stream",
+NULL));
 break;
 case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-caps_ss << "image/jpeg";
+sink_caps.reset(gst_caps_new_empty_simple("image/jpeg"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP8:
-caps_ss << "video/x-vp8";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp8"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP9:
-caps_ss << "video/x-vp9";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp9"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_H265:
-caps_ss << "video/x-h265";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-h265"));
 break;
 default : /* Should not happen - just to avoid compiler's complaint */
 throw std::logic_error("Unknown codec");
 }
-caps_ss << ",framerate=" << settings.fps << "/1";
+gst_caps_set_simple(sink_caps.get(), "framerate", GST_TYPE_FRACTION, 
settings.fps, 1, nullptr);
+std::unique_ptr caps_str(gst_caps_to_string(sink_caps.get()));
 
 encoders = 
gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER, 
GST_RANK_NONE);
-sink_caps.reset(gst_caps_from_string(caps_ss.str().c_str()));
 filtered = gst_element_factory_list_filter(encoders, sink_caps.get(), 
GST_PAD_SRC, false);
 if (filtered) {
-gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_ss.str().c_str());
+gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_str.get());
 for (GList *l = filtered; l != nullptr; l = l->next) {
 if (!factory && 
!settings.encoder.compare(GST_ELEMENT_NAME(l->data))) {
 factory = (GstElementFactory*)l->data;
@@ -169,13 +169,13 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 if (!factory && !settings.encoder.empty()) {
 gst_syslog(LOG_WARNING,
"Specified encoder named '%s' cannot produce '%s' 
stream, make sure matching gst.codec is specified and plugin's availability",
-   settings.encoder.c_str(), caps_ss.str().c_str());
+   settings.encoder.c_str(), caps_str.get());
 }
 factory = factory ? factory : (GstElementFactory*)filtered->data;
 gst_syslog(LOG_NOTICE, "'%s' encoder plugin is used", 
GST_ELEMENT_NAME(factory));
 
 } else {
-gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_ss.str().c_str());
+gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_str.get());
 }
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
@@ -351,10 +351,12 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
-std::stringstream ss;
-
-ss << "video/x-raw,format=BGRx,width=" << image->width << ",height=" << 
image->height << ",framerate=" << settings.fps << "/1";
-GstCapsUPtr caps(gst_caps_from_string(ss.str().c_str()));
+GstCapsUPtr caps(gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "BGRx",
+ "width", G_TYPE_INT, image->width,
+ "height", G_TYPE_INT, image->height,
+ "framerate", GST_TYPE_FRACTION, 
settings.fps, 1,
+ NULL));
 
 // Push sample
 GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, 
nullptr));
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent v2 2/2] gst-plugin: Use autovideoconvert element for color space conversion

2019-06-27 Thread Snir Sheriber
When VAAPI based encoder is used it's likely that also VAAPI based
conversion is available (using the vaapipostproc element).
Moving to autovideoconvert will automatically choose a suitable
convert element according to elements availability (e.g. in the
VAAPI case it would select vaapipostproc due to its high rank).

Signed-off-by: Snir Sheriber 
Acked-by: Frediano Ziglio 
---
Basically Acked, for the record I'm sending it again with the minor changes
---
 src/gst-plugin.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 0dd7796..3887b47 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -216,9 +216,9 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 if (!capture) {
 throw std::runtime_error("Gstreamer's capture element cannot be 
created");
 }
-GstObjectUPtr convert(gst_element_factory_make("videoconvert", 
"convert"));
+GstObjectUPtr 
convert(gst_element_factory_make("autovideoconvert", "convert"));
 if (!convert) {
-throw std::runtime_error("Gstreamer's 'videoconvert' element cannot be 
created");
+throw std::runtime_error("Gstreamer's 'autovideoconvert' element 
cannot be created");
 }
 GstCapsUPtr sink_caps;
 GstObjectUPtr encoder(get_encoder_plugin(settings, sink_caps));
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-streaming-agent 1/2] gst-plugin: Drop sstream and use dedicated functions instead

2019-06-27 Thread Snir Sheriber

Hi,


On 6/26/19 6:24 PM, Frediano Ziglio wrote:

Signed-off-by: Snir Sheriber 

Can you explain why this is better? It's not clear from the code.



Actually it is not much better, it just seems more reasonable to me
to set this properties using a dedicated function than manipulating
a string and and then convert it.





---
  src/gst-plugin.cpp | 33 +
  1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..cf660eb 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -8,7 +8,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
@@ -132,34 +131,33 @@ GstElement
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
  GList *filtered;
  GstElement *encoder;
  GstElementFactory *factory = nullptr;
-std::stringstream caps_ss;
  
  switch (settings.codec) {

  case SPICE_VIDEO_CODEC_TYPE_H264:
-caps_ss << "video/x-h264" << ",stream-format=(string)byte-stream";
+sink_caps.reset(gst_caps_new_simple("video/x-h264", "stream-format",
G_TYPE_STRING, "byte-stream", nullptr));
  break;
  case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-caps_ss << "image/jpeg";
+sink_caps.reset(gst_caps_new_empty_simple("image/jpeg"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_VP8:
-caps_ss << "video/x-vp8";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp8"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_VP9:
-caps_ss << "video/x-vp9";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp9"));
  break;
  case SPICE_VIDEO_CODEC_TYPE_H265:
-caps_ss << "video/x-h265";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-h265"));
  break;
  default : /* Should not happen - just to avoid compiler's complaint */
  throw std::logic_error("Unknown codec");
  }
-caps_ss << ",framerate=" << settings.fps << "/1";
+gst_caps_set_simple(sink_caps.get(), "framerate", GST_TYPE_FRACTION,
settings.fps, 1, nullptr);
+gchar *caps_str = gst_caps_to_string(sink_caps.get());

As we are using exception I would avoid using naked pointers.



Will send another proposal

Snir.




  
  encoders =

  
gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER,
  GST_RANK_NONE);
-sink_caps.reset(gst_caps_from_string(caps_ss.str().c_str()));
  filtered = gst_element_factory_list_filter(encoders, sink_caps.get(),
  GST_PAD_SRC, false);
  if (filtered) {
-gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can
produce a '%s' stream", caps_ss.str().c_str());
+gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can
produce a '%s' stream", caps_str);
  for (GList *l = filtered; l != nullptr; l = l->next) {
  if (!factory &&
  !settings.encoder.compare(GST_ELEMENT_NAME(l->data))) {
  factory = (GstElementFactory*)l->data;
@@ -169,14 +167,15 @@ GstElement
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
  if (!factory && !settings.encoder.empty()) {
  gst_syslog(LOG_WARNING,
 "Specified encoder named '%s' cannot produce '%s'
 stream, make sure matching gst.codec is specified
 and plugin's availability",
-   settings.encoder.c_str(), caps_ss.str().c_str());
+   settings.encoder.c_str(), caps_str);
  }
  factory = factory ? factory : (GstElementFactory*)filtered->data;
  gst_syslog(LOG_NOTICE, "'%s' encoder plugin is used",
  GST_ELEMENT_NAME(factory));
  
  } else {

-gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'",
caps_ss.str().c_str());
+gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'",
caps_str);
  }
+g_free(caps_str);

This line should not exist.

  
  encoder = factory ? gst_element_factory_create(factory, "encoder") :

  nullptr;
  if (encoder) { // Invalid properties will be ignored silently
@@ -351,10 +350,12 @@ void GstreamerFrameCapture::xlib_capture()
  throw std::runtime_error("Failed to wrap image in gstreamer
  buffer");
  }
  
-std::stringstream ss;

-
-ss << "video/x-raw,format=BGRx,width=" << image->width << ",height=" <<
image->height << "

Re: [Spice-devel] [PATCH spice-streaming-agent 2/2] gst-plugin: Use autovideoconvert element for color space conversion

2019-06-27 Thread Snir Sheriber


On 6/27/19 10:43 AM, Frediano Ziglio wrote:

When vaapi based encoder is used it's likely that also vaapi based
conversion is available (using the vaapipostproc element).
Moving to autovideoconvert will automatically choose a suitable
convert element according to elements availability (e.g. in the
vaapi case it would select vaapipostproc due to its high rank).

Signed-off-by: Snir Sheriber 

Really minor: vaapi -> VAAPI ?



Sure




Acked-by: Frediano Ziglio 


---
At first i had a patch to choose vaapipostproc manually but then i remembered
this element
which suppose to do it automatically (it seems vaapipostproc has high enough
rank). I think
it's preferred although it's in gst-plugins-bad
---
  src/gst-plugin.cpp | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index cf660eb..d8e2d89 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -215,7 +215,7 @@ void GstreamerFrameCapture::pipeline_init(const
GstreamerEncoderSettings &settin
  if (!capture) {
  throw std::runtime_error("Gstreamer's capture element cannot be
  created");
  }
-GstObjectUPtr
convert(gst_element_factory_make("videoconvert", "convert"));
+GstObjectUPtr
convert(gst_element_factory_make("autovideoconvert", "convert"));
  if (!convert) {
  throw std::runtime_error("Gstreamer's 'videoconvert' element cannot
  be created");

Change 'videoconvert' to 'audiovideoconvert' here?



Yes, Missed that.

Snir.





  }

Frediano

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent 2/2] gst-plugin: Use autovideoconvert element for color space conversion

2019-06-26 Thread Snir Sheriber
When vaapi based encoder is used it's likely that also vaapi based
conversion is available (using the vaapipostproc element).
Moving to autovideoconvert will automatically choose a suitable
convert element according to elements availability (e.g. in the
vaapi case it would select vaapipostproc due to its high rank).

Signed-off-by: Snir Sheriber 
---
At first i had a patch to choose vaapipostproc manually but then i remembered 
this element
which suppose to do it automatically (it seems vaapipostproc has high enough 
rank). I think
it's preferred although it's in gst-plugins-bad
---
 src/gst-plugin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index cf660eb..d8e2d89 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -215,7 +215,7 @@ void GstreamerFrameCapture::pipeline_init(const 
GstreamerEncoderSettings &settin
 if (!capture) {
 throw std::runtime_error("Gstreamer's capture element cannot be 
created");
 }
-GstObjectUPtr convert(gst_element_factory_make("videoconvert", 
"convert"));
+GstObjectUPtr 
convert(gst_element_factory_make("autovideoconvert", "convert"));
 if (!convert) {
 throw std::runtime_error("Gstreamer's 'videoconvert' element cannot be 
created");
 }
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent 1/2] gst-plugin: Drop sstream and use dedicated functions instead

2019-06-26 Thread Snir Sheriber
Signed-off-by: Snir Sheriber 
---
 src/gst-plugin.cpp | 33 +
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp
index 9858beb..cf660eb 100644
--- a/src/gst-plugin.cpp
+++ b/src/gst-plugin.cpp
@@ -8,7 +8,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -132,34 +131,33 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 GList *filtered;
 GstElement *encoder;
 GstElementFactory *factory = nullptr;
-std::stringstream caps_ss;
 
 switch (settings.codec) {
 case SPICE_VIDEO_CODEC_TYPE_H264:
-caps_ss << "video/x-h264" << ",stream-format=(string)byte-stream";
+sink_caps.reset(gst_caps_new_simple("video/x-h264", "stream-format", 
G_TYPE_STRING, "byte-stream", nullptr));
 break;
 case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-caps_ss << "image/jpeg";
+sink_caps.reset(gst_caps_new_empty_simple("image/jpeg"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP8:
-caps_ss << "video/x-vp8";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp8"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_VP9:
-caps_ss << "video/x-vp9";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-vp9"));
 break;
 case SPICE_VIDEO_CODEC_TYPE_H265:
-caps_ss << "video/x-h265";
+sink_caps.reset(gst_caps_new_empty_simple("video/x-h265"));
 break;
 default : /* Should not happen - just to avoid compiler's complaint */
 throw std::logic_error("Unknown codec");
 }
-caps_ss << ",framerate=" << settings.fps << "/1";
+gst_caps_set_simple(sink_caps.get(), "framerate", GST_TYPE_FRACTION, 
settings.fps, 1, nullptr);
+gchar *caps_str = gst_caps_to_string(sink_caps.get());
 
 encoders = 
gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER, 
GST_RANK_NONE);
-sink_caps.reset(gst_caps_from_string(caps_ss.str().c_str()));
 filtered = gst_element_factory_list_filter(encoders, sink_caps.get(), 
GST_PAD_SRC, false);
 if (filtered) {
-gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_ss.str().c_str());
+gst_syslog(LOG_NOTICE, "Looking for encoder plugins which can produce 
a '%s' stream", caps_str);
 for (GList *l = filtered; l != nullptr; l = l->next) {
 if (!factory && 
!settings.encoder.compare(GST_ELEMENT_NAME(l->data))) {
 factory = (GstElementFactory*)l->data;
@@ -169,14 +167,15 @@ GstElement 
*GstreamerFrameCapture::get_encoder_plugin(const GstreamerEncoderSett
 if (!factory && !settings.encoder.empty()) {
 gst_syslog(LOG_WARNING,
"Specified encoder named '%s' cannot produce '%s' 
stream, make sure matching gst.codec is specified and plugin's availability",
-   settings.encoder.c_str(), caps_ss.str().c_str());
+   settings.encoder.c_str(), caps_str);
 }
 factory = factory ? factory : (GstElementFactory*)filtered->data;
 gst_syslog(LOG_NOTICE, "'%s' encoder plugin is used", 
GST_ELEMENT_NAME(factory));
 
 } else {
-gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_ss.str().c_str());
+gst_syslog(LOG_ERR, "No suitable encoder was found for '%s'", 
caps_str);
 }
+g_free(caps_str);
 
 encoder = factory ? gst_element_factory_create(factory, "encoder") : 
nullptr;
 if (encoder) { // Invalid properties will be ignored silently
@@ -351,10 +350,12 @@ void GstreamerFrameCapture::xlib_capture()
 throw std::runtime_error("Failed to wrap image in gstreamer buffer");
 }
 
-std::stringstream ss;
-
-ss << "video/x-raw,format=BGRx,width=" << image->width << ",height=" << 
image->height << ",framerate=" << settings.fps << "/1";
-GstCapsUPtr caps(gst_caps_from_string(ss.str().c_str()));
+GstCapsUPtr caps(gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "BGRx",
+ "width", G_TYPE_INT, image->width,
+ "height", G_TYPE_INT, image->height,
+ "framerate", GST_TYPE_FRACTION, 
settings.fps, 1,
+ nullptr));
 
 // Push sample
 GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, 
nullptr));
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] display-channel: Avoid potential crash from buggy guest driver

2019-06-20 Thread Snir Sheriber

Seems fine to me.

Ack

On 6/17/19 7:13 PM, Frediano Ziglio wrote:

This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1582137.

Signed-off-by: Frediano Ziglio 
---
  server/display-channel.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/server/display-channel.c b/server/display-channel.c
index 071c01409..7ddd44c14 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -2032,7 +2032,11 @@ void display_channel_update(DisplayChannel *display,
  SpiceRect rect;
  RedSurface *surface;
  
-spice_return_if_fail(display_channel_validate_surface(display, surface_id));

+// Check that the request is valid, the surface_id comes directly from the 
guest
+if (!display_channel_validate_surface(display, surface_id)) {
+// just return, display_channel_validate_surface already logged a 
warning
+return;
+}
  
  red_get_rect_ptr(&rect, area);

  display_channel_draw(display, &rect, surface_id);

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [client v2 07/12] channel-display: Minimize the stream lag by ignoring the server one

2019-06-20 Thread Snir Sheriber

Hi,

On 6/17/19 8:33 PM, Francois Gouget wrote:

The client is in a better position than the server to pick the minimum
lag needed to compensate for frame arrival time jitter and ensure
smooth video playback.
To do so:
- It ignores the lag specified by the server through the mmtime clock
   adjustments (but this lag is still tracked for the stream reports).
- It performs its own frame mmtime conversion to the local monotonic
   clock spice_session_get_client_time() since the server-controlled
   mmtime clock cannot be relied on. This conversion uses data from all
   streams but is global so all streams ihave a common time reference.

have (has?)

- This is also where mmtime clock changes caused by server migration
   are handled.
- It tracks the margin between the converted time-to-display frame
   timestamp and the curren time and adds a delay to ensure this margin
   remains positive.
- This delay introduces the video stream lag. It is continuously
   adjusted to either be as low as possible, or match the audio
   playback delay for proper lip sync.
- Delay adjustments are gradual, speeding up or slowing down video
   playback until the average margin matches the target lag.


It seems once margin increase it's not decrease.
(i tested with streaming agent after playing a video for several seconds
margin goes up and latency stays), do we want gradual changes when
it's full screen streaming?

Generally speaking it makes the code more complex and hard to
follow (maybe worth more comments and variables description)
how do you test it? does it improve significantly the smoothness of
video streams?



- Changes in the average margin are tracked (see margin_spread) to
   avoid nudging the delay in response to minor random variations.

Signed-off-by: Francois Gouget 
---
  src/channel-display-gst.c   |  22 ++---
  src/channel-display-mjpeg.c |  14 +--
  src/channel-display-priv.h  |  18 +++-
  src/channel-display.c   | 178 
  src/spice-session-priv.h|   1 +
  src/spice-session.c |  46 ++
  6 files changed, 240 insertions(+), 39 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 6fccf621..673f4177 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -50,7 +50,7 @@ typedef struct SpiceGstDecoder {
  
  /* -- Decoding and display queues -- */
  
-uint32_t last_mm_time;

+uint32_t last_frame_time;
  
  GMutex queues_mutex;

  GQueue *decoding_queue;
@@ -297,8 +297,8 @@ static void schedule_frame(SpiceGstDecoder *decoder)
  break;
  }
  
-if (spice_mmtime_diff(gstframe->encoded_frame->mm_time, now) >= 0) {

-decoder->timer_id = g_timeout_add(gstframe->encoded_frame->mm_time 
- now,
+if (spice_mmtime_diff(gstframe->encoded_frame->time, now) >= 0) {
+decoder->timer_id = g_timeout_add(gstframe->encoded_frame->time - 
now,
display_frame, decoder);
  } else if (decoder->display_frame && !decoder->pending_samples) {
  /* Still attempt to display the least out of date frame so the
@@ -307,8 +307,8 @@ static void schedule_frame(SpiceGstDecoder *decoder)
  decoder->timer_id = g_timeout_add(0, display_frame, decoder);
  } else {
  SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u), 
dropping",
-__FUNCTION__, now - gstframe->encoded_frame->mm_time,
-gstframe->encoded_frame->mm_time, now);
+__FUNCTION__, now - gstframe->encoded_frame->time,
+gstframe->encoded_frame->time, now);
  stream_dropped_frame_on_playback(decoder->base.stream);
  decoder->display_frame = NULL;
  free_gst_frame(gstframe);
@@ -449,9 +449,9 @@ sink_event_probe(GstPad *pad, GstPadProbeInfo *info, 
gpointer data)
   *   or more frame intervals.
   */
  record(frames_stats,
-   "frame mm_time %u size %u creation time %" PRId64
+   "frame time %u size %u creation time %" PRId64
 " decoded time %" PRId64 " queue %u before %u",
-   frame->mm_time, frame->size, frame->creation_time, duration,
+   frame->time, frame->size, frame->creation_time, duration,
 decoder->decoding_queue->length, gstframe->queue_len);
  
  if (!decoder->appsink) {

@@ -689,13 +689,13 @@ static gboolean 
spice_gst_decoder_queue_frame(VideoDecoder *video_decoder,
  return TRUE;
  }
  
-if (spice_mmtime_diff(frame->mm_time, decoder->last_mm_time) < 0) {

+if (spice_mmtime_diff(frame->time, decoder->last_frame_time) < 0) {
  SPICE_DEBUG("new-frame-time < last-frame-time (%u < %u):"
  " resetting stream",
-frame->mm_time, decode

Re: [Spice-devel] [PATCH spice-common] build: Disable Celt support by default

2019-06-13 Thread Snir Sheriber

Hi,

Fine with me.

On 6/12/19 3:06 PM, Frediano Ziglio wrote:

We started disabling Celt support making the option required.
After 2 releases start making it disabled unless explicitly
enabled.

Signed-off-by: Frediano Ziglio 
---
  m4/spice-deps.m4  | 14 ++
  meson_options.txt |  1 +
  2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/m4/spice-deps.m4 b/m4/spice-deps.m4
index 02230dd..1214341 100644
--- a/m4/spice-deps.m4
+++ b/m4/spice-deps.m4
@@ -101,21 +101,11 @@ AC_DEFUN([SPICE_CHECK_SMARTCARD], [
  AC_DEFUN([SPICE_CHECK_CELT051], [
  AC_ARG_ENABLE([celt051],
  AS_HELP_STRING([--enable-celt051],
-   [Enable celt051 audio codec @<:@default=auto@:>@]),,
-[enable_celt051="auto"])
+   [Enable celt051 audio codec @<:@default=no@:>@]),,
+[enable_celt051="no"])
  
  if test "x$enable_celt051" != "xno"; then

  PKG_CHECK_MODULES([CELT051], [celt051 >= 0.5.1.1], 
[have_celt051=yes], [have_celt051=no])
-if test "x$enable_celt051" = "xauto"; then
-if test "x$have_celt051" = "xyes"; then
-AC_MSG_ERROR(m4_normalize([
-CELT 0.5.1.x has been detected, \
-but CELT support is no longer automatically 
enabled by default. \
-Please explicitly use --enable-celt051 or 
--disable-celt051
- ]))
-fi
-# have_celt051 is "no" here, so celt is disabled by default
-fi
  if test "x$enable_celt051" = "xyes" && test "x$have_celt051" != 
"xyes"; then
  AC_MSG_ERROR(["--enable-celt051 has been specified, but CELT 0.5.1 is 
missing"])
  fi
diff --git a/meson_options.txt b/meson_options.txt
index 7e9e704..c982736 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -12,6 +12,7 @@ option('extra-checks',
  
  option('celt051',

  type : 'feature',
+value : 'disabled',
  yield : true,
  description: 'Enable celt051 audio codec')
  



___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] Update spice-common submodule

2019-06-13 Thread Snir Sheriber

It seems this was pushed already some time ago

On 6/12/19 2:53 PM, Frediano Ziglio wrote:

This brings in the following changes:

Frediano Ziglio (4):
   gitignore: Ignore auto generated generated_messages.h file
   Do not check for HAVE_CONFIG_H
   build: Remove unused git-version-gen file
   recorder: Update

Uri Lublin (1):
   codegen Makefile: add common/ to --include client_marshallers.h

Signed-off-by: Frediano Ziglio 
---
  subprojects/spice-common | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/subprojects/spice-common b/subprojects/spice-common
index 47ba8e0f2..cc109a83b 16
--- a/subprojects/spice-common
+++ b/subprojects/spice-common
@@ -1 +1 @@
-Subproject commit 47ba8e0f25ddba110fe77ba55ad5da570f4582bd
+Subproject commit cc109a83b6c6a9205a229e84246079dbf540abf7

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] ci: Remove dependencies from copr build

2019-06-13 Thread Snir Sheriber


Assuming it passed the CI, Ack.

Acked-by: Snir Sheriber 

On 6/12/19 6:13 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  .gitlab-ci.yml | 13 -
  1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 91ee47edc..e21ea97de 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -79,12 +79,15 @@ distcheck:
  makecheck-centos:
before_script:
  - >
-  yum install git libtool make libasan orc-devel
-  python3 python3-six python3-pyparsing glib-networking
-  yum-utils yum-plugin-copr
+  yum install git libtool make libasan orc-devel glib-networking
+  yum-utils gcc glib2-devel celt051-devel
+  opus-devel pixman-devel openssl-devel libjpeg-devel
+  libcacard-devel cyrus-sasl-devel lz4-devel
+  gstreamer1-devel gstreamer1-plugins-base-devel
+  git-core pyparsing python-six
-y
-- yum copr enable @spice/nightly -y
-- yum-builddep spice -y
+- git clone ${CI_REPOSITORY_URL/spice.git/spice-protocol.git}
+- (cd spice-protocol && ./autogen.sh --prefix=/usr && make install)
image: centos:latest
script:
- >

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [client] gstreamer: Fix the decoding time when not using GstVideoOverlay

2019-06-12 Thread Snir Sheriber

Hi,

On 6/11/19 9:42 PM, Francois Gouget wrote:

schedule_frame() only pulls frames out of GStreamer's pipeline once all
previous decoded frames have been displayed. Thus when the video delay



IIRC we used to pull when samples arrived but it was changed to this so 
pending frames will be queued

inside gstreamer and let it do throttling (or something similar)



is high a decoded frame may have to wait for several frame intervals
before get_decoded_frame() looks at it and computes its decoding time.

So attach decoded frame samples to the corresponding decoding_queue
entry as soon as new_sample() is called, and compute the decoding time
and associated statistics then. Similarly, match sink_event_probe()'s
new buffer to a decoding_queue entry and update the statistics in the
process. This ensures that there is no extra delay in either case.

Signed-off-by: Francois Gouget 
---
  src/channel-display-gst.c | 183 --
  1 file changed, 96 insertions(+), 87 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 91ece0fa..fed73592 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -1,6 +1,6 @@
  /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
  /*
-   Copyright (C) 2015-2016 CodeWeavers, Inc
+   Copyright (C) 2015-2016, 2019 CodeWeavers, Inc
  
 This library is free software; you can redistribute it and/or

 modify it under the terms of the GNU Lesser General Public
@@ -54,9 +54,9 @@ typedef struct SpiceGstDecoder {
  
  GMutex queues_mutex;

  GQueue *decoding_queue;
+guint decoded_frames;
  SpiceGstFrame *display_frame;
  guint timer_id;
-guint pending_samples;
  } SpiceGstDecoder;
  
  #define VALID_VIDEO_CODEC_TYPE(codec) \

@@ -120,8 +120,6 @@ static void free_gst_frame(SpiceGstFrame *gstframe)
  /* -- GStreamer pipeline -- */
  
  static void schedule_frame(SpiceGstDecoder *decoder);

-static void fetch_pending_sample(SpiceGstDecoder *decoder);
-static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer 
*buffer);
  
  RECORDER(frames_stats, 64, "Frames statistics");
  
@@ -191,21 +189,26 @@ static void schedule_frame(SpiceGstDecoder *decoder)

  g_mutex_lock(&decoder->queues_mutex);
  
  while (!decoder->timer_id) {

-while (decoder->display_frame == NULL && decoder->pending_samples) {
-fetch_pending_sample(decoder);
+GList *head = g_queue_peek_head_link(decoder->decoding_queue);
+if (!head) {
+/* No frame in the queue */
+break;
  }
-
-SpiceGstFrame *gstframe = decoder->display_frame;
-if (!gstframe) {
+SpiceGstFrame *gstframe = head->data;
+if (!gstframe->decoded_sample) {
+/* This frame has not been decoded yet */
  break;
  }
+g_queue_pop_head(decoder->decoding_queue);
+decoder->display_frame = gstframe;
+decoder->decoded_frames--;
  
  if (spice_mmtime_diff(gstframe->encoded_frame->mm_time, now) >= 0) {

  decoder->timer_id = 
g_timeout_add(gstframe->encoded_frame->mm_time - now,
display_frame, decoder);
-} else if (decoder->display_frame && !decoder->pending_samples) {
-/* Still attempt to display the least out of date frame so the
- * video is not completely frozen for an extended period of time.
+} else if (decoder->display_frame && decoder->decoded_frames == 0) {
+/* This is the least out of date frame. Display it since that's
+ * better than having frozen video for an extended period of time.
   */
  decoder->timer_id = g_timeout_add(0, display_frame, decoder);
  } else {
@@ -221,12 +224,16 @@ static void schedule_frame(SpiceGstDecoder *decoder)
  g_mutex_unlock(&decoder->queues_mutex);
  }
  
-/* Get the decoded frame relative to buffer or NULL if not found.

- * Dequeue the frame from decoding_queue and return it, caller
- * is responsible to free the pointer.
+/* Returns the decoding queue entry that matches the specified GStreamer 
buffer.
+ *
+ * The entry is identified based on the buffer timestamp. However sometimes
+ * GStreamer returns the same buffer twice (and the second time the entry may
+ * have been removed already) or buffers that have a modified, and thus
+ * unrecognizable, timestamp. In such cases NULL is returned.
+ *
   * queues_mutex must be held.
   */
-static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer 
*buffer)
+static GList *find_decoded_entry(SpiceGstDecoder *decoder, GstBuffer *buffer)
  {
  GstClockTime buffer_ts = GST_BUFFER_PTS(buffer);
  #if GST_CHECK_VERSION(1,14,0)
@@ -238,81 +245,71 @@ static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder 
*decoder, GstBuffer *buf
  }
  #endif
  
-/* Gstreamer sometimes returns the same buffer 

Re: [Spice-devel] [spice-gtk v4] Adjust to window scaling

2019-06-10 Thread Snir Sheriber


On 6/10/19 3:45 PM, Victor Toso wrote:

Hi,

On Mon, Jun 10, 2019 at 12:15:27PM +, Victor Toso wrote:

From: Snir Sheriber 

When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2

This issue was also reported at freedesktop gitlab repo:
https://gitlab.freedesktop.org/spice/spice-gtk/issues/99
---
  src/spice-widget-egl.c |  8 
  src/spice-widget.c | 31 +++
  2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..4c2a58e 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -360,9 +360,9 @@ gboolean spice_egl_realize_display(SpiceDisplay *display, 
GdkWindow *win, GError
  DISPLAY_DEBUG(display, "egl realize");
  if (!spice_widget_init_egl_win(display, win, err))
  return FALSE;
-
-spice_egl_resize_display(display, gdk_window_get_width(win),
- gdk_window_get_height(win));
+gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+spice_egl_resize_display(display, gdk_window_get_width(win) * scale_factor,
+ gdk_window_get_height(win) * scale_factor);
  
  return TRUE;

  }
@@ -427,7 +427,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
  }
  
  G_GNUC_INTERNAL

-void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h) // w and h 
should be adjusted to gdk scaling

Why not a comment before the function declaration?


  {
  SpiceDisplayPrivate *d = display->priv;
  int prog;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 1f2a154..a2651ff 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1382,7 +1382,8 @@ static void set_egl_enabled(SpiceDisplay *display, bool 
enabled)
  }
  
  if (enabled && d->egl.context_ready) {

-spice_egl_resize_display(display, d->ww, d->wh);
+gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+spice_egl_resize_display(display, d->ww * scale_factor, d->wh * 
scale_factor);
  }
  
  d->egl.enabled = enabled;

@@ -1978,11 +1979,16 @@ static void transform_input(SpiceDisplay *display,
  SpiceDisplayPrivate *d = display->priv;
  int display_x, display_y, display_w, display_h;
  double is;
+gint scale_factor = 1;
  
  spice_display_get_scaling(display, NULL,

&display_x, &display_y,
&display_w, &display_h);
-
+#if HAVE_EGL
+if (egl_enabled(d)) {
+scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+}
+#endif

I don't think this #if HAVE_EGL is needed because that's in
egl_enabled() too, in case egl is disabled it should always
return false which I hope compiler can optimize...


  /* For input we need a different scaling factor in order to
 be able to reach the full width of a display. For instance, consider
 a display of 100 pixels showing in a window 10 pixels wide. The normal
@@ -1998,7 +2004,7 @@ static void transform_input(SpiceDisplay *display,
 coordinates in the inverse direction (window -> display) as the fb size
 (display -> window).
  */
-is = (double)(d->area.width-1) / (double)(display_w-1);
+is = ((double)(d->area.width-1) / (double)(display_w-1)) * scale_factor;
  
  window_x -= display_x;

  window_y -= display_y;
@@ -2183,8 +2189,10 @@ static void size_allocate(GtkWidget *widget, 
GtkAllocation *conf, gpointer data)
  d->wh = conf->height;
  recalc_geometry(widget);
  #if HAVE_EGL
-if (egl_enabled(d))
-spice_egl_resize_display(display, conf->width, conf->height);
+if (egl_enabled(d)) {
+gint scale_factor = gtk_widget_get_scale_factor(widget);
+spice_egl_resize_display(display, conf->width * scale_factor, 
conf->height * scale_factor);
+}

Indentation is wrong



Will be fixed.





  #endif
  }
  
@@ -2942,10 +2950,16 @@ void spice_display_get_scaling(SpiceDisplay *display,

  int ww, wh;
  int x, y, w, h;
  double s;
+gint scale_factor = 1;
  
  if (gtk_widget_get_realized (GTK_WIDGET(display))) {

-ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
-wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+#if HAVE_EGL
+ 

Re: [Spice-devel] [client] gstreamer: Initialize last_mm_time to avoid an overflow

2019-06-10 Thread Snir Sheriber

Hi,


On 6/10/19 11:49 AM, Francois Gouget wrote:

The mm_time is an unsigned 32 bit int but spice_mmtime_diff() returns a
signed 32 bit int. That's reasonable because we normally substract



s/substract/subtract

Ack, I'll do this fix and push



frame times which should be at most seconds apart.
But last_mm_time was zero on stream startup, resulting in an overflow
and an uncalled for warning for the first frame in
spice_gst_decoder_queue_frame() if the uptime was greater than about
25 days.

Signed-off-by: Francois Gouget 
---
  src/channel-display-gst.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 88918f10..858e8aeb 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -740,6 +740,7 @@ VideoDecoder* create_gstreamer_decoder(int codec_type, 
display_stream *stream)
  decoder->base.queue_frame = spice_gst_decoder_queue_frame;
  decoder->base.codec_type = codec_type;
  decoder->base.stream = stream;
+decoder->last_mm_time = stream_get_time(stream);
  g_mutex_init(&decoder->queues_mutex);
  decoder->decoding_queue = g_queue_new();
  

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH v3 spice-gtk] Adjust to window scaling

2019-06-02 Thread Snir Sheriber

Hi,


On 5/27/19 8:29 PM, Marc-André Lureau wrote:

Hi

On Mon, May 27, 2019 at 10:04 AM Snir Sheriber  wrote:

When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2

This issue was also reported at freedesktop gitlab repo:
https://gitlab.freedesktop.org/spice/spice-gtk/issues/99
---
  src/spice-widget-egl.c |  8 
  src/spice-widget.c | 31 +++
  2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..f688fd2 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -360,9 +360,9 @@ gboolean spice_egl_realize_display(SpiceDisplay *display, 
GdkWindow *win, GError
  DISPLAY_DEBUG(display, "egl realize");
  if (!spice_widget_init_egl_win(display, win, err))
  return FALSE;
-
-spice_egl_resize_display(display, gdk_window_get_width(win),
- gdk_window_get_height(win));
+gint gdk_scale = gdk_window_get_scale_factor(win);

Here too, I suppose gtk_widget_get_scale_factor() would be better.



I used this for consistency although I'm still not sure which one is 
more consistent :P .
If I'm using gtk_* would make sense to get also the sizes with gtk_* 
function but then

passing the GdkWindow also seems a bit unnecessary..

Another version is attached





+spice_egl_resize_display(display, gdk_window_get_width(win) * gdk_scale,
+ gdk_window_get_height(win) * gdk_scale);

  return TRUE;
  }
@@ -427,7 +427,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
  }

  G_GNUC_INTERNAL
-void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h) // w and h 
should be adjusted to gdk scaling
  {
  SpiceDisplayPrivate *d = display->priv;
  int prog;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 1f2a154..c475c39 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1382,7 +1382,8 @@ static void set_egl_enabled(SpiceDisplay *display, bool 
enabled)
  }

  if (enabled && d->egl.context_ready) {
-spice_egl_resize_display(display, d->ww, d->wh);
+gint gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+spice_egl_resize_display(display, d->ww * gdk_scale, d->wh * 
gdk_scale);
  }

  d->egl.enabled = enabled;
@@ -1978,11 +1979,16 @@ static void transform_input(SpiceDisplay *display,
  SpiceDisplayPrivate *d = display->priv;
  int display_x, display_y, display_w, display_h;
  double is;
+gint gdk_scale = 1;

  spice_display_get_scaling(display, NULL,
&display_x, &display_y,
&display_w, &display_h);
-
+#if HAVE_EGL
+if (egl_enabled(d)) {
+gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+}
+#endif
  /* For input we need a different scaling factor in order to
 be able to reach the full width of a display. For instance, consider
 a display of 100 pixels showing in a window 10 pixels wide. The normal
@@ -1998,7 +2004,7 @@ static void transform_input(SpiceDisplay *display,
 coordinates in the inverse direction (window -> display) as the fb size
 (display -> window).
  */
-is = (double)(d->area.width-1) / (double)(display_w-1);
+is = ((double)(d->area.width-1) / (double)(display_w-1)) * gdk_scale;

  window_x -= display_x;
  window_y -= display_y;
@@ -2183,8 +2189,10 @@ static void size_allocate(GtkWidget *widget, 
GtkAllocation *conf, gpointer data)
  d->wh = conf->height;
  recalc_geometry(widget);
  #if HAVE_EGL
-if (egl_enabled(d))
-spice_egl_resize_display(display, conf->width, conf->height);
+if (egl_enabled(d)) {
+gint gdk_scale = gtk_widget_get_scale_factor(widget);
+spice_egl_resize_display(display, conf->width * gdk_scale, 
conf->height * gdk_scale);
+}
  #endif
  }

@@ -2942,10 +2950,16 @@ void spice_display_get_scaling(SpiceDisplay *display,
  int ww, wh;
  int x, y, w, h;
  double s;
+gint gdk_scale = 1;

  if (gtk_widget_get_realized (GTK_WIDGET(display))) {
-ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
-wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+#if HAVE_EGL
+if (egl_enabled(d)) {
+ 

Re: [Spice-devel] [PATCH spice-server 1/3] spicevmc: Reuse "sin" variable

2019-06-02 Thread Snir Sheriber

ack

On 6/1/19 3:14 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  server/spicevmc.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/spicevmc.c b/server/spicevmc.c
index 460edb04f..84bbb73c2 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -786,7 +786,7 @@ static void spicevmc_connect(RedChannel *channel, RedClient 
*client,
  return;
  }
  
-sif = spice_char_device_get_interface(vmc_channel->chardev_sin);

+sif = spice_char_device_get_interface(sin);
  if (sif->state) {
  sif->state(sin, 1);
  }

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] char-device: Fix some comments

2019-06-02 Thread Snir Sheriber

Acked-by: Snir Sheriber 

On 5/31/19 7:52 AM, Frediano Ziglio wrote:

Some function names where changed.

Signed-off-by: Frediano Ziglio 
---
  server/char-device.h | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/char-device.h b/server/char-device.h
index 62d2fa61e..b19560816 100644
--- a/server/char-device.h
+++ b/server/char-device.h
@@ -93,13 +93,13 @@ GType red_char_device_get_type(void) G_GNUC_CONST;
   * device attached: create new object instantiating a RedCharDevice child 
class
   * device detached: call g_object_unref/red_char_device_reset
   *
- * client connected and associated with a device: red_char_device__add
- * client disconnected: red_char_device__remove
+ * client connected and associated with a device: red_char_device_client_add
+ * client disconnected: red_char_device_client_remove
   *
   * Writing to the device
   * -
   * Write the data into RedCharDeviceWriteBuffer:
- * call 
red_char_device_write_buffer_get/red_char_device_write_buffer_get_server_no_token
+ * call 
red_char_device_write_buffer_get_client/red_char_device_write_buffer_get_server
   * in order to get an appropriate buffer.
   * call red_char_device_write_buffer_add in order to push the buffer to the 
write queue.
   * If you choose not to push the buffer to the device, call

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH v3 spice-gtk] Adjust to window scaling

2019-05-27 Thread Snir Sheriber
When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2

This issue was also reported at freedesktop gitlab repo:
https://gitlab.freedesktop.org/spice/spice-gtk/issues/99
---
 src/spice-widget-egl.c |  8 
 src/spice-widget.c | 31 +++
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..f688fd2 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -360,9 +360,9 @@ gboolean spice_egl_realize_display(SpiceDisplay *display, 
GdkWindow *win, GError
 DISPLAY_DEBUG(display, "egl realize");
 if (!spice_widget_init_egl_win(display, win, err))
 return FALSE;
-
-spice_egl_resize_display(display, gdk_window_get_width(win),
- gdk_window_get_height(win));
+gint gdk_scale = gdk_window_get_scale_factor(win);
+spice_egl_resize_display(display, gdk_window_get_width(win) * gdk_scale,
+ gdk_window_get_height(win) * gdk_scale);
 
 return TRUE;
 }
@@ -427,7 +427,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
 }
 
 G_GNUC_INTERNAL
-void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h) // w and h 
should be adjusted to gdk scaling
 {
 SpiceDisplayPrivate *d = display->priv;
 int prog;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 1f2a154..c475c39 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1382,7 +1382,8 @@ static void set_egl_enabled(SpiceDisplay *display, bool 
enabled)
 }
 
 if (enabled && d->egl.context_ready) {
-spice_egl_resize_display(display, d->ww, d->wh);
+gint gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+spice_egl_resize_display(display, d->ww * gdk_scale, d->wh * 
gdk_scale);
 }
 
 d->egl.enabled = enabled;
@@ -1978,11 +1979,16 @@ static void transform_input(SpiceDisplay *display,
 SpiceDisplayPrivate *d = display->priv;
 int display_x, display_y, display_w, display_h;
 double is;
+gint gdk_scale = 1;
 
 spice_display_get_scaling(display, NULL,
   &display_x, &display_y,
   &display_w, &display_h);
-
+#if HAVE_EGL
+if (egl_enabled(d)) {
+gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+}
+#endif
 /* For input we need a different scaling factor in order to
be able to reach the full width of a display. For instance, consider
a display of 100 pixels showing in a window 10 pixels wide. The normal
@@ -1998,7 +2004,7 @@ static void transform_input(SpiceDisplay *display,
coordinates in the inverse direction (window -> display) as the fb size
(display -> window).
 */
-is = (double)(d->area.width-1) / (double)(display_w-1);
+is = ((double)(d->area.width-1) / (double)(display_w-1)) * gdk_scale;
 
 window_x -= display_x;
 window_y -= display_y;
@@ -2183,8 +2189,10 @@ static void size_allocate(GtkWidget *widget, 
GtkAllocation *conf, gpointer data)
 d->wh = conf->height;
 recalc_geometry(widget);
 #if HAVE_EGL
-if (egl_enabled(d))
-spice_egl_resize_display(display, conf->width, conf->height);
+if (egl_enabled(d)) {
+gint gdk_scale = gtk_widget_get_scale_factor(widget);
+spice_egl_resize_display(display, conf->width * gdk_scale, 
conf->height * gdk_scale);
+}
 #endif
 }
 
@@ -2942,10 +2950,16 @@ void spice_display_get_scaling(SpiceDisplay *display,
 int ww, wh;
 int x, y, w, h;
 double s;
+gint gdk_scale = 1;
 
 if (gtk_widget_get_realized (GTK_WIDGET(display))) {
-ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
-wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+#if HAVE_EGL
+if (egl_enabled(d)) {
+gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+}
+#endif
+ww = gtk_widget_get_allocated_width(GTK_WIDGET(display)) * gdk_scale;
+wh = gtk_widget_get_allocated_height(GTK_WIDGET(display)) * gdk_scale;
 } else {
 ww = fbw;
 wh = fbh;
@@ -3091,7 +3105,8 @@ void spice_display_widget_gl_scanout(SpiceDisplay 
*display)
 g_clear_error(&err);
 }
 
-spice_egl_resize_display(display, d->ww, d->wh);
+gint gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+spice_egl_resize_display(

Re: [Spice-devel] [PATCH v2 spice-gtk] Adjust to window scaling

2019-05-27 Thread Snir Sheriber

Hi,

On 5/23/19 2:00 PM, Victor Toso wrote:

Hi,

On Thu, May 23, 2019 at 01:01:12PM +0300, Snir Sheriber wrote:

Hi,

On 5/22/19 6:02 PM, Marc-André Lureau wrote:

Hi

On Sun, Mar 17, 2019 at 4:28 PM Snir Sheriber  wrote:

When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2
---
Changes from v1:
-commit msg
-replace var naming (ws with win_scale)


This patch is kind of RFC, it fixes the issue, but it's a bit hacky
and specific. I didn't come across other scale issues but it is likely
that more of these exist and better and generic fix is needed.

---
   src/spice-widget-egl.c  | 15 +--
   src/spice-widget-priv.h |  1 +
   2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..600c87a 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -326,6 +326,8 @@ static gboolean spice_widget_init_egl_win(SpiceDisplay 
*display, GdkWindow *win,
   if (d->egl.surface)
   return TRUE;

+d->egl.scale = gdk_window_get_scale_factor(win);

Why not use gtk_widget_get_scale_factor() directly from
spice_egl_resize_display?

There is no special objection for that, just because i adjust
scaling also in spice_egl_update_display and i assumed scaling
is not being changed frequently.

But it can be changed, right? In that case, d->egl.scale would
not have the right value in spice_egl_resize_display()



Yes, if the user is changing his desktop scaling during running,
i guess this could be solved also by resetting this parameter
in the allocation / realize callback.

I'll follow this response with another version to this patch that
may be bit more reasonable

Snir



Note that user tested that this patches fixes so I'd add that to
commit log:

 https://gitlab.freedesktop.org/spice/spice-gtk/issues/99

Cheers,


Snir.


+
   #ifdef GDK_WINDOWING_X11
   if (GDK_IS_X11_WINDOW(win)) {
   native = (EGLNativeWindowType)GDK_WINDOW_XID(win);
@@ -431,15 +433,17 @@ void spice_egl_resize_display(SpiceDisplay *display, int 
w, int h)
   {
   SpiceDisplayPrivate *d = display->priv;
   int prog;
+gint win_scale;

   if (!gl_make_current(display, NULL))
   return;

+win_scale = d->egl.scale;
   glGetIntegerv(GL_CURRENT_PROGRAM, &prog);

   glUseProgram(d->egl.prog);
-apply_ortho(d->egl.mproj, 0, w, 0, h, -1, 1);
-glViewport(0, 0, w, h);
+apply_ortho(d->egl.mproj, 0, w * win_scale , 0, h * win_scale, -1, 1);
+glViewport(0, 0, w * win_scale, h * win_scale);

   if (d->ready)
   spice_egl_update_display(display);
@@ -559,6 +563,13 @@ void spice_egl_update_display(SpiceDisplay *display)

   spice_display_get_scaling(display, &s, &x, &y, &w, &h);

+// Adjust to gdk scale
+s *= d->egl.scale;
+x *= d->egl.scale;
+y *= d->egl.scale;
+w *= d->egl.scale;
+h *= d->egl.scale;
+
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
   glClear(GL_COLOR_BUFFER_BIT);

diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 65eb404..8f110ac 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -149,6 +149,7 @@ struct _SpiceDisplayPrivate {
   EGLImageKHR image;
   gbooleancall_draw_done;
   SpiceGlScanout  scanout;
+gintscale;
   } egl;
   #endif // HAVE_EGL
   double scroll_delta_y;
--
2.19.1

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel



___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH v2 spice-gtk] Adjust to window scaling

2019-05-23 Thread Snir Sheriber

Hi,

On 5/22/19 6:02 PM, Marc-André Lureau wrote:

Hi

On Sun, Mar 17, 2019 at 4:28 PM Snir Sheriber  wrote:

When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2
---
Changes from v1:
-commit msg
-replace var naming (ws with win_scale)


This patch is kind of RFC, it fixes the issue, but it's a bit hacky
and specific. I didn't come across other scale issues but it is likely
that more of these exist and better and generic fix is needed.

---
  src/spice-widget-egl.c  | 15 +--
  src/spice-widget-priv.h |  1 +
  2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..600c87a 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -326,6 +326,8 @@ static gboolean spice_widget_init_egl_win(SpiceDisplay 
*display, GdkWindow *win,
  if (d->egl.surface)
  return TRUE;

+d->egl.scale = gdk_window_get_scale_factor(win);

Why not use gtk_widget_get_scale_factor() directly from
spice_egl_resize_display?



There is no special objection for that, just because i adjust scaling 
also in spice_egl_update_display

and i assumed scaling is not being changed frequently.


Snir.


+
  #ifdef GDK_WINDOWING_X11
  if (GDK_IS_X11_WINDOW(win)) {
  native = (EGLNativeWindowType)GDK_WINDOW_XID(win);
@@ -431,15 +433,17 @@ void spice_egl_resize_display(SpiceDisplay *display, int 
w, int h)
  {
  SpiceDisplayPrivate *d = display->priv;
  int prog;
+gint win_scale;

  if (!gl_make_current(display, NULL))
  return;

+win_scale = d->egl.scale;
  glGetIntegerv(GL_CURRENT_PROGRAM, &prog);

  glUseProgram(d->egl.prog);
-apply_ortho(d->egl.mproj, 0, w, 0, h, -1, 1);
-glViewport(0, 0, w, h);
+apply_ortho(d->egl.mproj, 0, w * win_scale , 0, h * win_scale, -1, 1);
+glViewport(0, 0, w * win_scale, h * win_scale);

  if (d->ready)
  spice_egl_update_display(display);
@@ -559,6 +563,13 @@ void spice_egl_update_display(SpiceDisplay *display)

  spice_display_get_scaling(display, &s, &x, &y, &w, &h);

+// Adjust to gdk scale
+s *= d->egl.scale;
+x *= d->egl.scale;
+y *= d->egl.scale;
+w *= d->egl.scale;
+h *= d->egl.scale;
+
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT);

diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 65eb404..8f110ac 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -149,6 +149,7 @@ struct _SpiceDisplayPrivate {
  EGLImageKHR image;
  gbooleancall_draw_done;
  SpiceGlScanout  scanout;
+gintscale;
  } egl;
  #endif // HAVE_EGL
  double scroll_delta_y;
--
2.19.1

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel




___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] spice-client-gtk-module: Remove unused file

2019-05-20 Thread Snir Sheriber


On 5/20/19 10:13 AM, Frediano Ziglio wrote:

Hi,

Maybe worth mentioning it's leftover from pygtk/python bindings
not really critical, anyway, fine with me.


Do you have the commit or some hint on what to write?
I'm not aware of this feature.



I think it should have been removed in 96ed6b7a and missed.
So i guess same subject would work "pygtk: remove bindings leftover"

Snir.





Acked-by: Snir Sheriber 

On 5/17/19 1:41 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
   src/spice-client-gtk-module.c | 45 ---
   1 file changed, 45 deletions(-)
   delete mode 100644 src/spice-client-gtk-module.c

diff --git a/src/spice-client-gtk-module.c b/src/spice-client-gtk-module.c
deleted file mode 100644
index b82f1e34..
--- a/src/spice-client-gtk-module.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see
<http://www.gnu.org/licenses/>.
-*/
-#include "config.h"
-#include 
-
-void spice_register_classes (PyObject *d);
-void spice_add_constants(PyObject *module, const gchar *strip_prefix);
-extern PyMethodDef spice_functions[];
-
-DL_EXPORT(void) initSpiceClientGtk(void)
-{
-PyObject *m, *d;
-
-init_pygobject();
-
-m = Py_InitModule("SpiceClientGtk", spice_functions);
-if (PyErr_Occurred())
-Py_FatalError("can't init module");
-
-d = PyModule_GetDict(m);
-if (PyErr_Occurred())
-Py_FatalError("can't get dict");
-
-spice_register_classes(d);
-spice_add_constants(m, "SPICE_");
-
-if (PyErr_Occurred()) {
-Py_FatalError("can't initialise module SpiceClientGtk");
-}
-}

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-server] spice-experimental: Remove obsolete file

2019-05-19 Thread Snir Sheriber

Hi,


ack

(looks safe to remove but i didn't push yet (if someone want to object 
by tomorrow ))



On 5/18/19 10:55 AM, Frediano Ziglio wrote:

This header was removed in 2014 (3c6b4e415) as deprecated and added again
in 2015 (2e88eb705) as causing some issue with former Qemu versions.
After 4 years remove again, now there should not be any usage of it.

Signed-off-by: Frediano Ziglio 
---
  server/Makefile.am  |  1 -
  server/meson.build  |  1 -
  server/spice-experimental.h | 24 
  3 files changed, 26 deletions(-)
  delete mode 100644 server/spice-experimental.h

CI results https://gitlab.freedesktop.org/fziglio/spice/pipelines/37607

diff --git a/server/Makefile.am b/server/Makefile.am
index 7f260612..20adf65f 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -64,7 +64,6 @@ libspice_serverinclude_HEADERS =  \
spice-audio.h   \
spice-char.h\
spice-core.h\
-   spice-experimental.h\
spice-input.h   \
spice-migration.h   \
spice-qxl.h \
diff --git a/server/meson.build b/server/meson.build
index 34d8eef1..2ca43e9c 100644
--- a/server/meson.build
+++ b/server/meson.build
@@ -26,7 +26,6 @@ spice_server_headers = [
'spice-audio.h',
'spice-char.h',
'spice-core.h',
-  'spice-experimental.h',
'spice-input.h',
'spice-migration.h',
'spice-qxl.h',
diff --git a/server/spice-experimental.h b/server/spice-experimental.h
deleted file mode 100644
index 589e29bf..
--- a/server/spice-experimental.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2009-2015 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see .
-*/
-
-#ifndef SPICE_EXPERIMENTAL_H_
-#define SPICE_EXPERIMENTAL_H_
-
-#warning spice-experimental.h is deprecated
-
-#endif /* SPICE_EXPERIMENTAL_H_ */

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Re: [Spice-devel] [PATCH spice-gtk] spice-client-gtk-module: Remove unused file

2019-05-19 Thread Snir Sheriber

Hi,

Maybe worth mentioning it's leftover from pygtk/python bindings
not really critical, anyway, fine with me.


Acked-by: Snir Sheriber 

On 5/17/19 1:41 PM, Frediano Ziglio wrote:

Signed-off-by: Frediano Ziglio 
---
  src/spice-client-gtk-module.c | 45 ---
  1 file changed, 45 deletions(-)
  delete mode 100644 src/spice-client-gtk-module.c

diff --git a/src/spice-client-gtk-module.c b/src/spice-client-gtk-module.c
deleted file mode 100644
index b82f1e34..
--- a/src/spice-client-gtk-module.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
-   Copyright (C) 2010 Red Hat, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-#include "config.h"
-#include 
-
-void spice_register_classes (PyObject *d);
-void spice_add_constants(PyObject *module, const gchar *strip_prefix);
-extern PyMethodDef spice_functions[];
-
-DL_EXPORT(void) initSpiceClientGtk(void)
-{
-PyObject *m, *d;
-
-init_pygobject();
-
-m = Py_InitModule("SpiceClientGtk", spice_functions);
-if (PyErr_Occurred())
-Py_FatalError("can't init module");
-
-d = PyModule_GetDict(m);
-if (PyErr_Occurred())
-Py_FatalError("can't get dict");
-
-spice_register_classes(d);
-spice_add_constants(m, "SPICE_");
-
-if (PyErr_Occurred()) {
-Py_FatalError("can't initialise module SpiceClientGtk");
-}
-}

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Spice-devel] [PATCH spice-streaming-agent] Remove -Wchkp warning, deprecated in GCC 9

2019-05-13 Thread Snir Sheriber
Signed-off-by: Snir Sheriber 
---
 m4/manywarnings.m4 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index 4f701f4..3864100 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -116,7 +116,6 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC],
 -Wbuiltin-macro-redefined \
 -Wcast-align \
 -Wchar-subscripts \
--Wchkp \
 -Wclobbered \
 -Wcomment \
 -Wcomments \
-- 
2.21.0

___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

  1   2   3   4   5   >