mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 22:48:19 +00:00
This way the video encoder can actually count on a real estimate when it is initializing. Note that the server only creates a video stream if at least 20 bitmap 'blits' of the same size and type arrive, each within a maximum time interval from the previous one. So it was only keeping track of the frame to frame interval. Thus to get an average frame rate over all the 20 frames it's necessary to also keep track of the first_frame_time. Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
168 lines
6.4 KiB
C
168 lines
6.4 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 STREAM_H_
|
|
#define STREAM_H_
|
|
|
|
#include <glib.h>
|
|
#include "utils.h"
|
|
#include "mjpeg-encoder.h"
|
|
#include "common/region.h"
|
|
#include "red-channel.h"
|
|
#include "image-cache.h"
|
|
|
|
#define RED_STREAM_DETACTION_MAX_DELTA ((1000 * 1000 * 1000) / 5) // 1/5 sec
|
|
#define RED_STREAM_CONTINUS_MAX_DELTA (1000 * 1000 * 1000)
|
|
#define RED_STREAM_TIMEOUT (1000 * 1000 * 1000)
|
|
#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 ((uint64_t)5 * 1000 * 1000 * 1000) // 5 sec
|
|
#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 1000 // milliseconds
|
|
#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
|
|
|
|
/* move back to display_channel once struct private */
|
|
typedef struct DisplayChannel DisplayChannel;
|
|
|
|
typedef struct Stream Stream;
|
|
|
|
typedef struct StreamActivateReportItem {
|
|
PipeItem pipe_item;
|
|
uint32_t stream_id;
|
|
} StreamActivateReportItem;
|
|
|
|
enum {
|
|
STREAM_FRAME_NONE,
|
|
STREAM_FRAME_NATIVE,
|
|
STREAM_FRAME_CONTAINER,
|
|
};
|
|
|
|
#define STREAM_STATS
|
|
#ifdef STREAM_STATS
|
|
typedef 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;
|
|
} StreamStats;
|
|
#endif
|
|
|
|
typedef struct StreamAgent {
|
|
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 */
|
|
|
|
PipeItem create_item;
|
|
PipeItem destroy_item;
|
|
Stream *stream;
|
|
uint64_t last_send_time;
|
|
MJpegEncoder *mjpeg_encoder;
|
|
DisplayChannelClient *dcc;
|
|
|
|
int frames;
|
|
int drops;
|
|
int fps;
|
|
|
|
uint32_t report_id;
|
|
uint32_t client_required_latency;
|
|
#ifdef STREAM_STATS
|
|
StreamStats stats;
|
|
#endif
|
|
} StreamAgent;
|
|
|
|
typedef struct StreamClipItem {
|
|
PipeItem base;
|
|
int refs;
|
|
StreamAgent *stream_agent;
|
|
int clip_type;
|
|
SpiceClipRects *rects;
|
|
} StreamClipItem;
|
|
|
|
StreamClipItem * stream_clip_item_new (DisplayChannelClient* dcc,
|
|
StreamAgent *agent);
|
|
void stream_clip_item_unref (DisplayChannelClient *dcc,
|
|
StreamClipItem *item);
|
|
|
|
typedef 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;
|
|
} ItemTrace;
|
|
|
|
struct Stream {
|
|
uint8_t refs;
|
|
Drawable *current;
|
|
red_time_t last_time;
|
|
int width;
|
|
int height;
|
|
SpiceRect dest_area;
|
|
int top_down;
|
|
Stream *next;
|
|
RingItem link;
|
|
|
|
uint32_t num_input_frames;
|
|
uint64_t input_fps_start_time;
|
|
uint32_t input_fps;
|
|
};
|
|
|
|
void display_channel_init_streams (DisplayChannel *display);
|
|
void stream_stop (DisplayChannel *display,
|
|
Stream *stream);
|
|
void stream_unref (DisplayChannel *display,
|
|
Stream *stream);
|
|
void stream_trace_update (DisplayChannel *display,
|
|
Drawable *drawable);
|
|
void stream_maintenance (DisplayChannel *display,
|
|
Drawable *candidate,
|
|
Drawable *prev);
|
|
void stream_timeout (DisplayChannel *display);
|
|
void stream_detach_and_stop (DisplayChannel *display);
|
|
void stream_trace_add_drawable (DisplayChannel *display,
|
|
Drawable *item);
|
|
void stream_detach_behind (DisplayChannel *display,
|
|
QRegion *region,
|
|
Drawable *drawable);
|
|
|
|
void stream_agent_unref (DisplayChannel *display,
|
|
StreamAgent *agent);
|
|
void stream_agent_stats_print (StreamAgent *agent);
|
|
void stream_agent_stop (StreamAgent *agent);
|
|
|
|
void detach_stream(DisplayChannel *display, Stream *stream, int detach_sized);
|
|
|
|
#endif /* STREAM_H */
|