Skip to content

Commit

Permalink
#1694 re-add webp codec with better speed and quality tuning
Browse files Browse the repository at this point in the history
git-svn-id: https://xpra.org/svn/Xpra/trunk@17468 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Nov 22, 2017
1 parent 3019700 commit 5457514
Show file tree
Hide file tree
Showing 24 changed files with 1,000 additions and 38 deletions.
8 changes: 8 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ Recommends:
# for the proxy server:
,python-setproctitle
# AES encryption:
,libxvidcore4
#webp
#stretch: ,libwebp6
#xenial: ,libwebp5
#zesty: ,libwebp6
#artful: ,libwebp6
,python-cryptography
# audio-related:
,gstreamer1.0-pulseaudio
Expand Down Expand Up @@ -106,6 +112,8 @@ Recommends:
#for using SSH passwords from the GUI launcher:
,sshpass
Suggests: openssh-server
# optional - only really useful with GPU opencl implementations:
,python-pyopencl
# for sound forwarding (server side):
,pulseaudio
,pulseaudio-utils
Expand Down
23 changes: 19 additions & 4 deletions osx/jhbuild/xpra.modules
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@
</after>
</autotools>

<autotools id="libwebp" autogenargs="" autogen-sh="configure">
<branch module="/releases/webp/libwebp-0.6.0.tar.gz"
version="0.6.0"
hash="sha256:c928119229d4f8f35e20113ffb61f281eda267634a8dc2285af4b0ee27cf2b40"
repo="downloads.webmproject.org"/>
<dependencies>
<dep package="libjpeg"/>
<dep package="libpng"/>
<dep package="libtiff"/>
</dependencies>
</autotools>

<autotools id="ffmpeg"
autogen-template="%(srcdir)s/%(autogen-sh)s --prefix=%(prefix)s %(autogenargs)s"
autogenargs="--enable-runtime-cpudetect --enable-pic
Expand Down Expand Up @@ -540,9 +552,11 @@
version="4.3.0"/>
<dependencies>
<dep package="python"/>
<dep package="libwebp"/>
</dependencies>
<after>
<dep package="python"/>
<dep package="libwebp"/>
</after>
</distutils>

Expand Down Expand Up @@ -656,10 +670,10 @@


<distutils id="python-lz4">
<branch repo="pypi.python.org"
module="/packages/f5/c6/ef2890b5e287735576e15c1389aa0b9032c9d78ed72385fbd1149af593cd/lz4-0.10.1.tar.gz"
hash="sha256:a0423290a6e89c1789525a7e9d344d877c7a97102cf5c0f99b2319ac560f1b3e"
version="0.10.1"/>
<branch repo="github.com"
module="/python-lz4/python-lz4/archive/v0.11.1.tar.gz"
hash="sha256:bb6554663a944723c2f05aa789f70ec8c18212c6543f5f161db0f21b5cf66d0c"
version="0.11.1"/>
<dependencies>
<dep package="python"/>
<dep package="python-setuptools-scm"/>
Expand Down Expand Up @@ -957,6 +971,7 @@
<dep package="libyuv"/>
<dep package="libvpx"/>
<dep package="x264"/>
<dep package="libwebp"/>
<dep package="ffmpeg"/>
<!--
sdl doesn't build with newer versions of osx because of missing X header files
Expand Down
95 changes: 95 additions & 0 deletions rpmbuild/libwebp-xpra.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
Name: libwebp-xpra
Version: 0.6.0
Release: 1%{?dist}
Summary: WebP library and conversion tools for xpra

Group: Applications/Multimedia
License: BSD
URL: https://developers.google.com/speed/webp/
Source0: http://downloads.webmproject.org/releases/webp/libwebp-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

BuildRequires: gcc
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool

%description
WebP library and conversion tools, private version for Xpra


%package devel
Summary: Development files for the webp library
Group: Development/libraries
Requires: %{name} = %{version}
Requires: pkgconfig

%description devel
This package contains the files required to develop programs that will encode
WebP images.

%prep
%if ! 0%{?el7}
echo "this package is only meant to be built for RHEL / CentOS 7.x"
exit 1
%endif
%setup -q -n libwebp-%{version}


%build
./configure \
--prefix="%{_prefix}" \
--libdir="%{_libdir}/xpra" \
--includedir="%{_includedir}/xpra" \
--enable-shared

make %{?_smp_mflags}


%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

rm -rf %{buildroot}/usr/bin
rm -rf %{buildroot}/usr/share


%clean
rm -rf %{buildroot}


%files
%defattr(-,root,root,-)
%doc AUTHORS COPYING PATENTS README
%{_libdir}/xpra/libwebp.so.*

%files devel
%defattr(-,root,root,-)
%{_includedir}/xpra/webp/
%{_libdir}/xpra/libwebp.a
%{_libdir}/xpra/libwebp.la
%{_libdir}/xpra/libwebp.so
%{_libdir}/xpra/pkgconfig/libwebp.pc


%changelog
* Wed Nov 22 2017 Antoine Martin <antoine@devloop.org.uk> 0.6.0-1
- new upstream release

* Fri Nov 13 2015 Antoine Martin <antoine@devloop.org.uk> 0.4.4-1
- new upstream release

* Tue Mar 31 2015 Antoine Martin <antoine@devloop.org.uk> 0.4.3-1
- new upstream release

* Sat Oct 25 2014 Antoine Martin <antoine@devloop.org.uk> 0.4.2-1
- new upstream release

* Mon Aug 18 2014 Antoine Martin <antoine@devloop.org.uk> 0.4.1-1
- Update to 0.4.1

* Thu Jul 31 2014 Antoine Martin <antoine@devloop.org.uk>
- configure doesn't support --enable-pic

* Mon Jul 14 2014 Matthew Gyurgyik <pyther@pyther.net>
- initial package
2 changes: 1 addition & 1 deletion src/add_build_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def record_build_info(is_build=True):
#record pkg-config versions:
PKG_CONFIG = os.environ.get("PKG_CONFIG", "pkg-config")
for pkg in ("libc",
"vpx", "libvpx", "x264", "x265",
"vpx", "libvpx", "x264", "x265", "webp",
"avcodec", "avutil", "swscale",
"nvenc",
"x11", "xrandr", "xtst", "xfixes", "xkbfile", "xcomposite", "xdamage", "xext",
Expand Down
5 changes: 3 additions & 2 deletions src/etc/xpra/conf.d/30_picture.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Encodings allowed:
# (not all encodings may be available in your environment):
#encodings = h264, vp8, png, png/P, png/L, rgb, jpeg, h265, vp9
#encodings = h264, vp8, png, png/P, png/L, webp, rgb, jpeg, h265, vp9
#encodings = all
#encodings = rgb
encodings = all
Expand All @@ -15,6 +15,8 @@ encodings = all
#encoding = png
#encoding = jpeg
#encoding = rgb
#encoding = webp
encoding = auto

# Used by the server to encode video:
# video-encoders = x264, vpx, nvenc
Expand All @@ -30,7 +32,6 @@ csc-modules = all

# Used by the client for decoding:
# video-decoders = avcodec2, vpx
# video-decoders = avcodec, vpx
# video-decoders = none
# video-decoders = all
video-decoders = all
Expand Down
6 changes: 5 additions & 1 deletion src/man/xpra.1
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ may be overridden on the client.
\fB\-\-encoding\fP=\fIENCODING\fP
This specifies the image encoding to use,
there are a number of encodings supported:
\fBjpeg\fP, \fBpng\fP, \fBpng/P\fP, \fBpng/L\fP, \fBrgb\fP, \fBvp8\fP, \fBvp9\fP, \fBh264\fP and \fBh265\fP
\fBjpeg\fP, \fBpng\fP, \fBpng/P\fP, \fBpng/L\fP, \fBwebp\fP, \fBrgb\fP, \fBvp8\fP, \fBvp9\fP, \fBh264\fP and \fBh265\fP
(some may not be available in your environment).
The default option is \fBauto\fP which allows the server to
select the best encoding automatically.
Expand All @@ -388,6 +388,10 @@ compressed and lossy: grayscale only using a palette.
.IP \fBrgb\fP
a raw pixel format (lossless) compressed with lz4, lzo or zlib (see \fIcompressors\fP)
the compression ratio is lower, but it is by far the fastest encoding available.
.IP \fBwebp\fP
can be used in lossy or lossless mode,
useful for graphical applications,
it compresses better than jpeg and is reasonably fast except at high resolutions.
.IP \fBjpeg\fP
can be useful for graphical applications,
it is lossy and usually very fast.
Expand Down
15 changes: 14 additions & 1 deletion src/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def is_RH():
enc_x264_ENABLED = DEFAULT and pkg_config_ok("--exists", "x264")
enc_x265_ENABLED = DEFAULT and pkg_config_ok("--exists", "x265")
pillow_ENABLED = DEFAULT
webp_ENABLED = DEFAULT and pkg_config_version("0.5", "libwebp")
jpeg_ENABLED = DEFAULT and pkg_config_version("1.4", "libturbojpeg")
vpx_ENABLED = DEFAULT and pkg_config_version("1.4", "vpx")
enc_ffmpeg_ENABLED = False
Expand Down Expand Up @@ -214,7 +215,7 @@ def is_RH():
#allow some of these flags to be modified on the command line:
SWITCHES = ["enc_x264", "enc_x265", "enc_ffmpeg",
"nvenc", "cuda_kernels", "cuda_rebuild", "nvfbc",
"vpx", "pillow", "jpeg",
"vpx", "webp", "pillow", "jpeg",
"v4l2",
"dec_avcodec2", "csc_swscale",
"csc_libyuv",
Expand Down Expand Up @@ -935,6 +936,8 @@ def convert_templates(subdirs=[]):
"xpra/codecs/v4l2/constants.pxi",
"xpra/codecs/v4l2/pusher.c",
"xpra/codecs/libav_common/av_log.c",
"xpra/codecs/webp/encode.c",
"xpra/codecs/webp/decode.c",
"xpra/codecs/dec_avcodec2/decoder.c",
"xpra/codecs/csc_libyuv/colorspace_converter.cpp",
"xpra/codecs/csc_swscale/colorspace_converter.c",
Expand Down Expand Up @@ -2062,6 +2065,16 @@ def which(cmd):
if pillow_ENABLED:
external_includes += ["PIL", "PIL.Image", "PIL.WebPImagePlugin"]

toggle_packages(webp_ENABLED, "xpra.codecs.webp")
if webp_ENABLED:
webp_pkgconfig = pkgconfig("webp")
cython_add(Extension("xpra.codecs.webp.encode",
["xpra/codecs/webp/encode.pyx"],
**webp_pkgconfig))
cython_add(Extension("xpra.codecs.webp.decode",
["xpra/codecs/webp/decode.pyx"],
**webp_pkgconfig))

toggle_packages(jpeg_ENABLED, "xpra.codecs.jpeg")
if jpeg_ENABLED:
jpeg_pkgconfig = pkgconfig("libturbojpeg")
Expand Down
4 changes: 2 additions & 2 deletions src/tests/xpra/clients/test_change_settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2014 Antoine Martin <antoine@devloop.org.uk>
# Copyright (C) 2014-2017 Antoine Martin <antoine@devloop.org.uk>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand Down Expand Up @@ -44,7 +44,7 @@ def do_command(self):
self.queue = []
for i in range(10):
self.queue.append(("command_request", "auto-refresh", "%.4f" % (i/100)))
for encoding in ("rgb", "png", "jpeg", "h264", "vp8"):
for encoding in ("rgb", "png", "jpeg", "h264", "vp8", "webp"):
self.queue.append(("command_request", "encoding", encoding, "strict"))
self.queue.append(("command_request", "quality", "*", 1))
self.queue.append(("command_request", "quality", "*", 100))
Expand Down
6 changes: 4 additions & 2 deletions src/tests/xpra/codecs/test_Pillow_perf.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2014 Antoine Martin <antoine@devloop.org.uk>
# Copyright (C) 2014-2017 Antoine Martin <antoine@devloop.org.uk>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand All @@ -13,7 +13,7 @@
from io import BytesIO


def do_test_encode(rgb_data, w, h, encodings=["png", "png/P", "png/L", "jpeg"], N=5, Q=[0, 50, 100], S=[0, 1, 50, 90, 100], has_alpha=False):
def do_test_encode(rgb_data, w, h, encodings=["png", "png/P", "png/L", "jpeg", "webp"], N=5, Q=[0, 50, 100], S=[0, 1, 50, 90, 100], has_alpha=False):
from xpra.codecs.pillow.encode import encode
from xpra.codecs.image_wrapper import ImageWrapper
image = ImageWrapper(0, 0, w, h, rgb_data, "BGRA", 32, w*4, planes=ImageWrapper.PACKED, thread_safe=True)
Expand All @@ -24,6 +24,8 @@ def do_test_encode(rgb_data, w, h, encodings=["png", "png/P", "png/L", "jpeg"],
if encoding in ("png", "png/P", "png/L"):
Q_options = [-1]
S_options = S
if encoding=="webp":
S_options = [-1]
if encoding in ("jpeg"):
S_options = [0, -1]
for q in Q_options:
Expand Down
6 changes: 3 additions & 3 deletions src/xpra/client/gtk_base/client_launcher.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2009-2014 Antoine Martin <antoine@devloop.org.uk>
# Copyright (C) 2009-2017 Antoine Martin <antoine@devloop.org.uk>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand Down Expand Up @@ -496,7 +496,7 @@ def get_selected_encoding(self, *_args):

def encoding_changed(self, *args):
encoding = self.get_selected_encoding()
uses_quality_option = encoding in ["jpeg", "h264", "auto"]
uses_quality_option = encoding in ["jpeg", "webp", "h264", "auto"]
log("encoding_changed(%s) uses_quality_option(%s)=%s", args, encoding, uses_quality_option)
if uses_quality_option:
self.quality_combo.show()
Expand Down Expand Up @@ -1012,4 +1012,4 @@ def may_show():

if __name__ == "__main__":
v = main()
sys.exit(v)
sys.exit(v)
1 change: 1 addition & 0 deletions src/xpra/client/paint_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"vp8" : "green",
"rgb24" : "orange",
"rgb32" : "red",
"webp" : "pink",
"jpeg" : "purple",
"png/P" : "indigo",
"png/L" : "teal",
Expand Down
9 changes: 5 additions & 4 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -740,14 +740,14 @@ def get_window_icon_encodings(self):
def do_get_core_encodings(self):
"""
This method returns the actual encodings supported.
ie: ["rgb24", "vp8", "png", "png/L", "png/P", "jpeg", "h264", "vpx"]
ie: ["rgb24", "vp8", "webp", "png", "png/L", "png/P", "jpeg", "h264", "vpx"]
It is often overriden in the actual client class implementations,
where extra encodings can be added (generally just 'rgb32' for transparency),
or removed if the toolkit implementation class is more limited.
"""
#we always support rgb24:
core_encodings = ["rgb24"]
for codec in ("dec_pillow", ):
for codec in ("dec_pillow", "dec_webp"):
if has_codec(codec):
c = get_codec(codec)
for e in c.get_encodings():
Expand Down Expand Up @@ -1539,6 +1539,7 @@ def make_hello(self):
"video_reinit" : True,
"video_scaling" : True,
"video_b_frames" : video_b_frames,
"webp_leaks" : False,
"transparency" : self.has_transparency(),
"rgb24zlib" : True,
"max-soft-expired" : MAX_SOFT_EXPIRED,
Expand Down Expand Up @@ -1877,7 +1878,7 @@ def parse_server_capabilities(self):
self.server_core_encodings = c.strlistget("encodings.core", self.server_encodings)
self.server_encodings_problematic = c.strlistget("encodings.problematic", PROBLEMATIC_ENCODINGS) #server is telling us to try to avoid those
self.server_encodings_with_speed = c.strlistget("encodings.with_speed", ("h264",)) #old servers only supported x264
self.server_encodings_with_quality = c.strlistget("encodings.with_quality", ("jpeg", "h264"))
self.server_encodings_with_quality = c.strlistget("encodings.with_quality", ("jpeg", "webp", "h264"))
self.server_encodings_with_lossless_mode = c.strlistget("encodings.with_lossless_mode", ())
self.server_auto_video_encoding = c.boolget("auto-video-encoding")
self.server_start_time = c.intget("start_time", -1)
Expand Down Expand Up @@ -2407,7 +2408,7 @@ def send_webcam_frame(self):
webcamlog.error(" the client supports: %s", csv(client_webcam_encodings))
self.stop_sending_webcam()
return False
preferred_order = ["jpeg", "png", "png/L", "png/P"]
preferred_order = ["jpeg", "png", "png/L", "png/P", "webp"]
formats = [x for x in preferred_order if x in common_encodings] + common_encodings
encoding = formats[0]
start = monotonic_time()
Expand Down
Loading

0 comments on commit 5457514

Please sign in to comment.