Commit Graph

2055 Commits

Author SHA1 Message Date
Frediano Ziglio
a46045a141 Make red_glz_drawable_free() static
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 15:12:34 +01:00
Frediano Ziglio
e92afe539b Encapsulate some data in dcc-encoders
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 15:12:20 +01:00
Pavel Grunt
58ed103636 Fix missing prototypes
Signed-off-by: Pavel Grunt <pgrunt@redhat.com>
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
2016-06-15 15:02:42 +01:00
Pavel Grunt
6a131e2cd1 Remove unused reds_expects_link_id
Not needed since f683815ad5

Signed-off-by: Pavel Grunt <pgrunt@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
2016-06-15 14:47:44 +01:00
Jonathon Jongsma
6bfeb5501c Rename image_encoders_free_glz_drawable()
Rename this function to red_glz_drawable_free() and remove the
ImageEncoders argument since the RedGlzDrawable already holds a pointer
to the ImageEncoders structure

Acked-by: Frediano Ziglio <fziglio@redhat.com>
2016-06-15 09:31:38 +01:00
Jonathon Jongsma
a6314d1782 Rename image_encoders_free_glz_drawable_instance()
Rename this function to glz_drawable_instance_item_free() and remove the
ImageEncoders argument since the RedGlzDrawable already holds a pointer
to the ImageEncoders structure.

Acked-by: Frediano Ziglio <fziglio@redhat.com>
2016-06-15 09:20:40 +01:00
Frediano Ziglio
afbad7231e Make image_encoders_freeze_glz() static
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 09:05:47 +01:00
Frediano Ziglio
b61c1ce030 Encapsulate code to save glz state
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 08:43:45 +01:00
Frediano Ziglio
49e2899ea8 Change RedGlzDrawable::drawable from pointer to boolean
The field was used just as a flag.
This has the advantage to make clear to not use the pointer as we don't
have ownership.
Also makes the structure a bit smaller.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 08:33:37 +01:00
Frediano Ziglio
9939496a93 Better encoders encapsulation
Avoid to access some fields from dcc.c

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 08:22:21 +01:00
Frediano Ziglio
49273f2011 Encapsulate dcc_release_glz
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-15 08:18:07 +01:00
Francois Gouget
0503cd3d61 streaming: Add support for GStreamer 0.10
configure will use GStreamer 1.0 if present and fall back to
GStreamer 0.10 otherwise.
ffenc_mjpeg takes its bitrate as a long so extend set_gstenc_bitrate().

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
b64b9e5657 streaming: Dynamically adjust the GStreamer encoder bitrate if possible
This is faster and lets the encoder leverage past bitrate shaping
history to attain the target faster.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
fc68e2e5ba streaming: Respect the GStreamer encoder's valid bit rate range
GObject returns an error instead of clamping if given an out of range
property value.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
c6f6471eb8 streaming: Give up after a while if GStreamer cannot handle the video
This typically happens when sending very small frames (less than
16 pixels in one dimension) to the x264enc encoder.
This avoids repeatedly wasting time rebuilding the pipeline.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
ef6d6b063d streaming: Adjust the frame rate based on the GStreamer encoding time
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
669d7090ca streaming: Adjust the GStreamer encoder bit rate to the network
The video encoder uses the client reports and/or notifications of
server frame drops as its feedback mechanisms. In particular it keeps
track of the maximum video margin and reduces the bit rate whenever the
margin goes below certain thresholds or decreases too sharply.
It uses these to figure out the lowest bit rate that causes negative
feedback, and the highest bit rate that allows a return to positive
feedbacks. It then works to narrow this range and settles on the lower
end once the spread has gone below a given threshold.
All the while it monitors the effective bit rate to ensure the target
bit rate does not grow significantly beyond what the GStreamer encoder
will produce: this avoids target bit rate 'bubbles' which would
invariably be followed by a bit rate crash with accompanying frame loss.
As soon as the network feedback indicates a significant degradation the
bit rate is lowered to minimize the risk of frame loss and/or long
freezes.
It also relies on the existing shaping of the GStreamer output bit rate
to minimize the pipeline reconfigurations.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
4f04c9ac79 streaming: Shape the bit rate of the GStreamer codecs output
The GStreamer codecs don't follow the specified bit rate very closely:
they can decide to exceed it for ten seconds or more if they consider
the scene deserves it. Such long bursts are enough to cause network
congestion, resulting in many lost frames which cause significant
display corruption.
So the GStreamer video encoder now uses a short 300ms virtual buffer
to shape the compressed video output and ensure we don't exceed the
target bit rate for any significant length of time.
It could instead rely on the network feedback (when available) to lower
the bit rate. However frequent GStreamer bit rate changes lower the
overall compression level and also result in a lower average bit rate,
both of which result in lower video quality.
The GStreamer video encoder also keeps track of the encoded frame size
so it can gather statistics and call update_client_playback_delay()
with accurate information and also annotate the client report debug
traces with the corresponding bit rate information.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
a21ec4e251 streaming: Add h264 support to the GStreamer video encoder
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
49036e6aae streaming: Avoid copying the input frame in the GStreamer encoder
Note that we can only avoid copies for the first 1 Mpixels or so.
That's because Spice splits larger frames into more chunks than we can
fit GstMemory fragments in a GStreamer buffer. So if there are more
pixels we will avoid copies for the first 3840 KB and copy the rest.
Furthermore, while in practice the GStreamer encoder will only modify
the RedDrawable refcount during the encode_frame(), in theory the
refcount could be decremented from the GStreamer thread after
encode_frame() returns.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
a6795d1971 streaming: Handle and recover from GStreamer encoding errors
If an error occurs for whatever reason (e.g. codec not supporting odd
frame sizes), the GStreamer pipeline will drop the current buffer,
causing the encoder to be stuck waiting for the sample. So this patch
tracks error notifications and ensures we don't wait for a sample if
none will come.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
2db59fef3a streaming: Let the video encoder manage the compressed buffer
This way the video encoder is not forced to use malloc()/free().
This also allows more flexibility in how the video encoder manages the
buffer which allows for a zero-copy implementation in both video
encoders.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
6dc0dadf8d streaming: Add VP8 support to the GStreamer video encoder
Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Pavel Grunt
ce6113d838 replay: Add an option to change video codec 2016-06-14 17:04:40 +02:00
Francois Gouget
497fcbb0a3 streaming: Let the administrator pick the video encoder and codec
The Spice server administrator can specify the encoder and codec
preferences to optimize for CPU or bandwidth usage. Preferences are
described in a semi-colon separated list of encoder:codec pairs.
The server has a default preference list which can explicitly be
selected by specifying 'auto'.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
f4414af48c streaming: Check the client video codec capabilities
The server picks a codec supported by the client based on the following
new client capabilities:
 * SPICE_DISPLAY_CAP_MULTI_CODEC which denotes a recent client that
   supports multiple codecs. This capability is needed to not have to
   hardcode that MJPEG is supported. This makes it possible to write
   clients that don't support MJPEG.
 * SPICE_DISPLAY_CAP_CODEC_XXX, where XXX is a supported codec. Note
   that for now the server only supports the MJPEG codec.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
a697bd971b streaming: Add a GStreamer 1.0 MJPEG video encoder and use it by default
This introduces a pared down GStreamer-based video encoder to serve as
the basis for later enhancements.
In this form the new encoder supports both regular and sized streams
but lacks any rate control. It should still work fine if bandwidth is
sufficient such as on LANs.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
1b69198c4e streaming: Remove the width/height encode_frame() parameters
encode_frame() needs the QXL_DRAW_COPY operation's SpiceCopy.src_area
field anyway, so the width and height parameters were redundant.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
032cb0ce85 mjpeg: Use src_area as the authoritative source for the frame dimensions
Video frames correspond to QXL_DRAW_COPY operations where the frame area
is defined by the SpiceCopy.src_area field.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
618255168e streaming: Simplify is_next_stream_frame()
After the removal of Drawable::sized_stream, we no longer need to detect
if the stream changes size in is_next_stream_frame() so it can return a
boolean rather than a value from an enum.
2016-06-14 17:04:40 +02:00
Francois Gouget
47509b1e6e streaming: Remove unused detach_stream() argument
After the removal of Drawable::sized_stream, the last argument to
detach_stream() is no longer used.
2016-06-14 17:04:40 +02:00
Francois Gouget
42a5794845 streaming: Remove the Drawable.sized_stream field
Only red_marshall_stream_data() needs to know whether to send the frame
using a SpiceMsgDisplayStreamDataSized or a regular StreamData message.
So check whether we have a sized frame there and simplify the rest of
the code.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Francois Gouget
28f2e425c4 streaming: Rework red_marshall_stream_data a bit
This code just refactors the function without doing any functional
changes. The actual changes will be in the next commit, and this will
make the next commit much more obvious.
2016-06-14 17:04:40 +02:00
Francois Gouget
709c9d71f1 streaming: Better check for sized frames
Usually the RedDrawable bbox dimensions match the src_area dimensions
so that checking that the bbox matches the stream's original dest_area
should be enough to determine if sized stream support is needed to
send the frame.
But making the bbox different could be used to have the scaling be
performed on the client side. So it's better not to assume the bbox and
src_area have the same dimensions.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
2016-06-14 17:04:40 +02:00
Frediano Ziglio
81f3d44ee7 Move image_encoders_compress_glz to dcc-encoders.c
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:31 +01:00
Frediano Ziglio
cb8e832c87 Make dcc_compress_image_glz independent to DisplayChannelClient
Also rename to image_encoders_compress_glz

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:31 +01:00
Frediano Ziglio
108d11f4aa Move others glz fields to dcc-encoders
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:31 +01:00
Frediano Ziglio
41231aa4f8 Change dcc_encoders_init to take ImageEncoders instead of DisplayChannelClient
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:29 +01:00
Frediano Ziglio
b46984ed30 Move some glz fields to ImageEncoders
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:28 +01:00
Frediano Ziglio
86b702a7d0 Add a structure to hold ImageEncoders shared data
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-14 15:07:23 +01:00
snir sheriber
903c91cd30 LZ4 compression is now available at the Spicevmc channel
Compressed message type is CompressedData which contains compression
type (1 byte) followed by the uncompressed data size (4 bytes - exists
only if data was compressed) followed by the compressed data

If SPICE_USBREDIR_CAP_DATA_COMPRESS_LZ4 capability is available &&
data_size > COMPRESS_THRESHOLD && !AF_LOCAL data will be sent
compressed otherwise data will be sent uncompressed (also if
compression has failed)

Update the required protocol to 0.12.12

Signed-off-by: Snir Sheriber <ssheribe@redhat.com>
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
2016-06-13 23:12:59 +01:00
Frediano Ziglio
6e29efadbc Remove unused DCC_TO_WORKER macro
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
2016-06-10 13:36:00 +01:00
Frediano Ziglio
9c5a8d5bce More encapsulation for dcc_encoders_free
Encoders function should not use DisplayChannelClient

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-10 09:15:24 +01:00
Frediano Ziglio
c2bc754559 Encapsulate zlib information in ImageEncoders structure
This change is less clean the other similar patches as zlib and
glz require more steps.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-10 09:15:17 +01:00
Frediano Ziglio
21a90ae986 Move image_encoders_compress_lz4 to dcc-encoders.c
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:50:12 +01:00
Frediano Ziglio
aa10a2ca2a Prepare to move dcc_compress_image_lz4 to ImageEncoders
Remove all DisplayChannel(Client) dependencies.
Rename function.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:50:10 +01:00
Frediano Ziglio
6d70d15d64 Encapsulate lz4 information in ImageEncoders structure
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:50:02 +01:00
Frediano Ziglio
25c0b204c4 Move image_encoders_compress_jpeg to dcc-encoders.c
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:32:50 +01:00
Frediano Ziglio
9d92a2edc8 Prepare to move dcc_compress_image_jpeg to ImageEncoders
Remove all DisplayChannel(Client) dependencies.
Rename function.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:32:48 +01:00
Frediano Ziglio
7b6cb37cc0 Encapsulate jpeg information in ImageEncoders structure
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2016-06-09 22:32:26 +01:00