mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
Do not offset the time attempting to fix client latency. Client should handle it by itself. This remove entirely the delay introduced by the server. This avoids surely possible time drifts in the client. The server just sends it's concept of time without trying to force any delay. Only one end should handle this delay in an attempt to synchronize audio and video instead that doing it in both ends. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> --- Changes since v1: - more deep clean; - remove the RFC intention; - remove some test notes not strictly related.
148 lines
4.8 KiB
C
148 lines
4.8 KiB
C
/* -*- 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef VIDEO_STREAM_H_
|
|
#define VIDEO_STREAM_H_
|
|
|
|
#include <glib.h>
|
|
#include <common/region.h>
|
|
|
|
#include "utils.h"
|
|
#include "video-encoder.h"
|
|
#include "red-channel.h"
|
|
#include "dcc.h"
|
|
|
|
#include "push-visibility.h"
|
|
|
|
#define RED_STREAM_DETECTION_MAX_DELTA (NSEC_PER_SEC / 5)
|
|
#define RED_STREAM_CONTINUOUS_MAX_DELTA NSEC_PER_SEC
|
|
#define RED_STREAM_TIMEOUT NSEC_PER_SEC
|
|
#define RED_STREAM_FRAMES_START_CONDITION 20
|
|
#define RED_STREAM_GRADUAL_FRAMES_START_CONDITION 0.2
|
|
#define RED_STREAM_FRAMES_RESET_CONDITION 100
|
|
#define RED_STREAM_MIN_SIZE (96 * 96)
|
|
#define RED_STREAM_INPUT_FPS_TIMEOUT (NSEC_PER_SEC * 5)
|
|
#define RED_STREAM_CHANNEL_CAPACITY 0.8
|
|
/* the client's stream report frequency is the minimum of the 2 values below */
|
|
#define RED_STREAM_CLIENT_REPORT_WINDOW 5 // #frames
|
|
#define RED_STREAM_CLIENT_REPORT_TIMEOUT MSEC_PER_SEC
|
|
#define RED_STREAM_DEFAULT_HIGH_START_BIT_RATE (10 * 1024 * 1024) // 10Mbps
|
|
#define RED_STREAM_DEFAULT_LOW_START_BIT_RATE (2.5 * 1024 * 1024) // 2.5Mbps
|
|
#define MAX_FPS 30
|
|
|
|
struct VideoStream;
|
|
|
|
#ifdef STREAM_STATS
|
|
struct StreamStats {
|
|
uint64_t num_drops_pipe;
|
|
uint64_t num_drops_fps;
|
|
uint64_t num_frames_sent;
|
|
uint64_t num_input_frames;
|
|
uint64_t size_sent;
|
|
|
|
uint64_t start;
|
|
uint64_t end;
|
|
};
|
|
#endif
|
|
|
|
struct VideoStreamAgent {
|
|
QRegion vis_region; /* the part of the surface area that is currently occupied by video
|
|
fragments */
|
|
QRegion clip; /* the current video clipping. It can be different from vis_region:
|
|
for example, let c1 be the clip area at time t1, and c2
|
|
be the clip area at time t2, where t1 < t2. If c1 contains c2, and
|
|
at least part of c1/c2, hasn't been covered by a non-video images,
|
|
vis_region will contain c2 and also the part of c1/c2 that still
|
|
displays fragments of the video */
|
|
|
|
VideoStream *stream;
|
|
VideoEncoder *video_encoder;
|
|
DisplayChannelClient *dcc;
|
|
|
|
uint32_t report_id;
|
|
#ifdef STREAM_STATS
|
|
StreamStats stats;
|
|
#endif
|
|
};
|
|
|
|
struct VideoStreamClipItem: public RedPipeItem {
|
|
VideoStreamClipItem(VideoStreamAgent *agent);
|
|
~VideoStreamClipItem();
|
|
|
|
VideoStreamAgent *stream_agent;
|
|
int clip_type;
|
|
red::glib_unique_ptr<SpiceClipRects> rects;
|
|
};
|
|
|
|
struct StreamCreateDestroyItem: public RedPipeItem {
|
|
StreamCreateDestroyItem(VideoStreamAgent *agent, int type);
|
|
~StreamCreateDestroyItem();
|
|
VideoStreamAgent *agent;
|
|
};
|
|
|
|
struct ItemTrace {
|
|
red_time_t time;
|
|
red_time_t first_frame_time;
|
|
int frames_count;
|
|
int gradual_frames_count;
|
|
int last_gradual_frame;
|
|
int width;
|
|
int height;
|
|
SpiceRect dest_area;
|
|
};
|
|
|
|
struct VideoStream {
|
|
uint8_t refs;
|
|
Drawable *current;
|
|
red_time_t last_time;
|
|
int width;
|
|
int height;
|
|
uint32_t stride;
|
|
SpiceRect dest_area;
|
|
int top_down;
|
|
VideoStream *next;
|
|
RingItem link;
|
|
|
|
uint32_t num_input_frames;
|
|
uint64_t input_fps_start_time;
|
|
uint32_t input_fps;
|
|
};
|
|
|
|
void display_channel_init_video_streams(DisplayChannel *display);
|
|
bool display_channel_create_gl_draw_stream(DisplayChannel *display);
|
|
bool display_channel_update_gl_draw_stream(DisplayChannelClient *dcc,
|
|
const SpiceMsgDisplayGlDraw *draw);
|
|
void video_stream_stop(DisplayChannel *display, VideoStream *stream);
|
|
void video_stream_trace_update(DisplayChannel *display, Drawable *drawable);
|
|
void video_stream_maintenance(DisplayChannel *display, Drawable *candidate,
|
|
Drawable *prev);
|
|
void video_stream_timeout(DisplayChannel *display);
|
|
void video_stream_detach_and_stop(DisplayChannel *display);
|
|
void video_stream_trace_add_drawable(DisplayChannel *display, Drawable *item);
|
|
void video_stream_detach_behind(DisplayChannel *display, QRegion *region,
|
|
Drawable *drawable);
|
|
GArray *video_stream_parse_preferred_codecs(SpiceMsgcDisplayPreferredVideoCodecType *msg);
|
|
|
|
void video_stream_agent_stop(VideoStreamAgent *agent);
|
|
|
|
void video_stream_detach_drawable(VideoStream *stream);
|
|
|
|
#include "pop-visibility.h"
|
|
|
|
#endif /* VIDEO_STREAM_H_ */
|