[Spice-commits] 3 commits - server/display-channel.h server/Makefile.am server/red_worker.c server/stream.c server/stream.h

Frediano Ziglio fziglio at kemper.freedesktop.org
Tue Nov 10 08:11:22 PST 2015


 server/Makefile.am       |    2 
 server/display-channel.h |   60 ----------------------
 server/red_worker.c      |  123 +++++++--------------------------------------
 server/stream.c          |   70 +++++++++++++++++++++++++
 server/stream.h          |  127 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 221 insertions(+), 161 deletions(-)

New commits:
commit 921ec344bc2cf651f6f4b1208e6a0d74dc32c62e
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Nov 10 12:46:55 2015 +0000

    worker: rename functions that handle DisplayChannelClient
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/red_worker.c b/server/red_worker.c
index 1d52551..8ebd0c9 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1540,7 +1540,7 @@ static inline void red_detach_stream(RedWorker *worker, Stream *stream, int deta
     stream->current = NULL;
 }
 
-static void push_stream_clip(DisplayChannelClient* dcc, StreamAgent *agent)
+static void dcc_push_stream_agent_clip(DisplayChannelClient* dcc, StreamAgent *agent)
 {
     StreamClipItem *item = stream_clip_item_new(dcc, agent);
     int n_rects;
@@ -1608,7 +1608,7 @@ static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *str
         if (!region_is_equal(&clip_in_draw_dest, &drawable->tree_item.base.rgn)) {
             region_remove(&agent->clip, &drawable->red_drawable->bbox);
             region_or(&agent->clip, &drawable->tree_item.base.rgn);
-            push_stream_clip(dcc, agent);
+            dcc_push_stream_agent_clip(dcc, agent);
         }
 #ifdef STREAM_STATS
         agent->stats.num_input_frames++;
@@ -1665,10 +1665,10 @@ static int red_display_drawable_is_in_pipe(DisplayChannelClient *dcc, Drawable *
 }
 
 /*
- * after red_display_detach_stream_gracefully is called for all the display channel clients,
+ * after dcc_detach_stream_gracefully is called for all the display channel clients,
  * red_detach_stream should be called. See comment (1).
  */
-static inline void red_display_detach_stream_gracefully(DisplayChannelClient *dcc,
+static inline void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
                                                         Stream *stream,
                                                         Drawable *update_area_limit)
 {
@@ -1677,7 +1677,7 @@ static inline void red_display_detach_stream_gracefully(DisplayChannelClient *dc
 
     /* stopping the client from playing older frames at once*/
     region_clear(&agent->clip);
-    push_stream_clip(dcc, agent);
+    dcc_push_stream_agent_clip(dcc, agent);
 
     if (region_is_empty(&agent->vis_region)) {
         spice_debug("stream %d: vis region empty", stream_id);
@@ -1742,7 +1742,7 @@ static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *strea
     DisplayChannelClient *dcc;
 
     FOREACH_DCC(worker->display_channel, item, next, dcc) {
-        red_display_detach_stream_gracefully(dcc, stream, update_area_limit);
+        dcc_detach_stream_gracefully(dcc, stream, update_area_limit);
     }
     if (stream->current) {
         red_detach_stream(worker, stream, TRUE);
@@ -1757,7 +1757,7 @@ static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *strea
  *           of the "current tree", the drawable parameter should be set with
  *           this drawable, otherwise, it should be NULL. Then, if detaching the stream
  *           involves sending an upgrade image to the client, this drawable won't be rendered
- *           (see red_display_detach_stream_gracefully).
+ *           (see dcc_detach_stream_gracefully).
  */
 static void red_detach_streams_behind(RedWorker *worker, QRegion *region, Drawable *drawable)
 {
@@ -1776,7 +1776,7 @@ static void red_detach_streams_behind(RedWorker *worker, QRegion *region, Drawab
             StreamAgent *agent = &dcc->stream_agents[get_stream_id(worker, stream)];
 
             if (region_intersects(&agent->vis_region, region)) {
-                red_display_detach_stream_gracefully(dcc, stream, drawable);
+                dcc_detach_stream_gracefully(dcc, stream, drawable);
                 detach_stream = 1;
                 spice_debug("stream %d", get_stream_id(worker, stream));
             }
@@ -1826,7 +1826,7 @@ static void red_streams_update_visible_region(RedWorker *worker, Drawable *drawa
             if (region_intersects(&agent->vis_region, &drawable->tree_item.base.rgn)) {
                 region_exclude(&agent->vis_region, &drawable->tree_item.base.rgn);
                 region_exclude(&agent->clip, &drawable->tree_item.base.rgn);
-                push_stream_clip(dcc, agent);
+                dcc_push_stream_agent_clip(dcc, agent);
             }
         }
     }
@@ -2013,7 +2013,7 @@ static void red_stream_update_client_playback_latency(void *opaque, uint32_t del
     main_dispatcher_set_mm_time_latency(RED_CHANNEL_CLIENT(agent->dcc)->client, agent->dcc->streams_max_latency);
 }
 
-static void red_display_create_stream(DisplayChannelClient *dcc, Stream *stream)
+static void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
 {
     StreamAgent *agent = &dcc->stream_agents[get_stream_id(DCC_TO_WORKER(dcc), stream)];
 
@@ -2094,7 +2094,7 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
     worker->streams_size_total += stream->width * stream->height;
     worker->stream_count++;
     FOREACH_DCC(worker->display_channel, dcc_ring_item, next, dcc) {
-        red_display_create_stream(dcc, stream);
+        dcc_create_stream(dcc, stream);
     }
     spice_debug("stream %d %dx%d (%d, %d) (%d, %d)", (int)(stream - worker->streams_buf), stream->width,
                 stream->height, stream->dest_area.left, stream->dest_area.top,
@@ -2102,18 +2102,18 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
     return;
 }
 
-static void red_disply_start_streams(DisplayChannelClient *dcc)
+static void dcc_create_all_streams(DisplayChannelClient *dcc)
 {
     Ring *ring = &DCC_TO_WORKER(dcc)->streams;
     RingItem *item = ring;
 
     while ((item = ring_next(ring, item))) {
         Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
-        red_display_create_stream(dcc, stream);
+        dcc_create_stream(dcc, stream);
     }
 }
 
-static void red_display_client_init_streams(DisplayChannelClient *dcc)
+static void dcc_init_stream_agents(DisplayChannelClient *dcc)
 {
     int i;
     RedWorker *worker = DCC_TO_WORKER(dcc);
@@ -2131,7 +2131,7 @@ static void red_display_client_init_streams(DisplayChannelClient *dcc)
         red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc), SPICE_DISPLAY_CAP_STREAM_REPORT);
 }
 
-static void red_display_destroy_streams_agents(DisplayChannelClient *dcc)
+static void dcc_destroy_stream_agents(DisplayChannelClient *dcc)
 {
     int i;
 
@@ -7711,7 +7711,7 @@ static void display_channel_client_on_disconnect(RedChannelClient *rcc)
     free(dcc->send_data.stream_outbuf);
     red_display_reset_compress_buf(dcc);
     free(dcc->send_data.free_list.res);
-    red_display_destroy_streams_agents(dcc);
+    dcc_destroy_stream_agents(dcc);
 
     // this was the last channel client
     if (!red_channel_is_connected(rcc->channel)) {
@@ -8139,7 +8139,7 @@ static void on_new_display_channel_client(DisplayChannelClient *dcc)
         red_push_surface_image(dcc, 0);
         dcc_push_monitors_config(dcc);
         red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_MARK);
-        red_disply_start_streams(dcc);
+        dcc_create_all_streams(dcc);
     }
 }
 
@@ -9018,7 +9018,7 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red
 
     // todo: tune level according to bandwidth
     display_channel->zlib_level = ZLIB_DEFAULT_COMPRESSION_LEVEL;
-    red_display_client_init_streams(dcc);
+    dcc_init_stream_agents(dcc);
     on_new_display_channel_client(dcc);
 }
 
commit 885557f117b77b4fb2e8cd92d90a90b961081af8
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Nov 10 11:57:38 2015 +0000

    worker: move stream functions to a new stream.c file
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/Makefile.am b/server/Makefile.am
index 8ccf614..52703c9 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -136,6 +136,7 @@ libspice_server_la_SOURCES =			\
 	spice-bitmap-utils.h			\
 	spice-bitmap-utils.c			\
 	utils.h					\
+	stream.c					\
 	stream.h					\
 	$(NULL)
 
diff --git a/server/red_worker.c b/server/red_worker.c
index b7428f1..1d52551 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1540,21 +1540,9 @@ static inline void red_detach_stream(RedWorker *worker, Stream *stream, int deta
     stream->current = NULL;
 }
 
-static StreamClipItem *__new_stream_clip(DisplayChannelClient* dcc, StreamAgent *agent)
-{
-    StreamClipItem *item = spice_new(StreamClipItem, 1);
-    red_channel_pipe_item_init(RED_CHANNEL_CLIENT(dcc)->channel,
-                    (PipeItem *)item, PIPE_ITEM_TYPE_STREAM_CLIP);
-
-    item->stream_agent = agent;
-    agent->stream->refs++;
-    item->refs = 1;
-    return item;
-}
-
 static void push_stream_clip(DisplayChannelClient* dcc, StreamAgent *agent)
 {
-    StreamClipItem *item = __new_stream_clip(dcc, agent);
+    StreamClipItem *item = stream_clip_item_new(dcc, agent);
     int n_rects;
 
     if (!item) {
@@ -1628,42 +1616,6 @@ static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *str
     }
 }
 
-static void red_print_stream_stats(DisplayChannelClient *dcc, StreamAgent *agent)
-{
-#ifdef STREAM_STATS
-    StreamStats *stats = &agent->stats;
-    double passed_mm_time = (stats->end - stats->start) / 1000.0;
-    MJpegEncoderStats encoder_stats = {0};
-
-    if (agent->mjpeg_encoder) {
-        mjpeg_encoder_get_stats(agent->mjpeg_encoder, &encoder_stats);
-    }
-
-    spice_debug("stream=%"PRIdPTR" dim=(%dx%d) #in-frames=%"PRIu64" #in-avg-fps=%.2f #out-frames=%"PRIu64" "
-                "out/in=%.2f #drops=%"PRIu64" (#pipe=%"PRIu64" #fps=%"PRIu64") out-avg-fps=%.2f "
-                "passed-mm-time(sec)=%.2f size-total(MB)=%.2f size-per-sec(Mbps)=%.2f "
-                "size-per-frame(KBpf)=%.2f avg-quality=%.2f "
-                "start-bit-rate(Mbps)=%.2f end-bit-rate(Mbps)=%.2f",
-                agent - dcc->stream_agents, agent->stream->width, agent->stream->height,
-                stats->num_input_frames,
-                stats->num_input_frames / passed_mm_time,
-                stats->num_frames_sent,
-                (stats->num_frames_sent + 0.0) / stats->num_input_frames,
-                stats->num_drops_pipe +
-                stats->num_drops_fps,
-                stats->num_drops_pipe,
-                stats->num_drops_fps,
-                stats->num_frames_sent / passed_mm_time,
-                passed_mm_time,
-                stats->size_sent / 1024.0 / 1024.0,
-                ((stats->size_sent * 8.0) / (1024.0 * 1024)) / passed_mm_time,
-                stats->size_sent / 1000.0 / stats->num_frames_sent,
-                encoder_stats.avg_quality,
-                encoder_stats.starting_bit_rate / (1024.0 * 1024),
-                encoder_stats.cur_bit_rate / (1024.0 * 1024));
-#endif
-}
-
 static void red_stop_stream(RedWorker *worker, Stream *stream)
 {
     DisplayChannelClient *dcc;
@@ -1691,7 +1643,7 @@ static void red_stop_stream(RedWorker *worker, Stream *stream)
         }
         stream->refs++;
         red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &stream_agent->destroy_item);
-        red_print_stream_stats(dcc, stream_agent);
+        stream_agent_stats_print(stream_agent);
     }
     worker->streams_size_total -= stream->width * stream->height;
     ring_remove(&stream->link);
diff --git a/server/stream.c b/server/stream.c
new file mode 100644
index 0000000..4545963
--- /dev/null
+++ b/server/stream.c
@@ -0,0 +1,70 @@
+/*
+   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/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "stream.h"
+#include "display-channel.h"
+
+void stream_agent_stats_print(StreamAgent *agent)
+{
+#ifdef STREAM_STATS
+    StreamStats *stats = &agent->stats;
+    double passed_mm_time = (stats->end - stats->start) / 1000.0;
+    MJpegEncoderStats encoder_stats = {0};
+
+    if (agent->mjpeg_encoder) {
+        mjpeg_encoder_get_stats(agent->mjpeg_encoder, &encoder_stats);
+    }
+
+    spice_debug("stream=%p dim=(%dx%d) #in-frames=%"PRIu64" #in-avg-fps=%.2f #out-frames=%"PRIu64" "
+                "out/in=%.2f #drops=%"PRIu64" (#pipe=%"PRIu64" #fps=%"PRIu64") out-avg-fps=%.2f "
+                "passed-mm-time(sec)=%.2f size-total(MB)=%.2f size-per-sec(Mbps)=%.2f "
+                "size-per-frame(KBpf)=%.2f avg-quality=%.2f "
+                "start-bit-rate(Mbps)=%.2f end-bit-rate(Mbps)=%.2f",
+                agent, agent->stream->width, agent->stream->height,
+                stats->num_input_frames,
+                stats->num_input_frames / passed_mm_time,
+                stats->num_frames_sent,
+                (stats->num_frames_sent + 0.0) / stats->num_input_frames,
+                stats->num_drops_pipe +
+                stats->num_drops_fps,
+                stats->num_drops_pipe,
+                stats->num_drops_fps,
+                stats->num_frames_sent / passed_mm_time,
+                passed_mm_time,
+                stats->size_sent / 1024.0 / 1024.0,
+                ((stats->size_sent * 8.0) / (1024.0 * 1024)) / passed_mm_time,
+                stats->size_sent / 1000.0 / stats->num_frames_sent,
+                encoder_stats.avg_quality,
+                encoder_stats.starting_bit_rate / (1024.0 * 1024),
+                encoder_stats.cur_bit_rate / (1024.0 * 1024));
+#endif
+}
+
+StreamClipItem *stream_clip_item_new(DisplayChannelClient* dcc, StreamAgent *agent)
+{
+    StreamClipItem *item = spice_new(StreamClipItem, 1);
+    red_channel_pipe_item_init(RED_CHANNEL_CLIENT(dcc)->channel,
+                               (PipeItem *)item, PIPE_ITEM_TYPE_STREAM_CLIP);
+
+    item->stream_agent = agent;
+    agent->stream->refs++;
+    item->refs = 1;
+    return item;
+}
diff --git a/server/stream.h b/server/stream.h
index 1587d4e..30b8624 100644
--- a/server/stream.h
+++ b/server/stream.h
@@ -103,6 +103,9 @@ typedef struct StreamClipItem {
     SpiceClipRects *rects;
 } StreamClipItem;
 
+StreamClipItem *stream_clip_item_new(DisplayChannelClient* dcc,
+                                     StreamAgent *agent);
+
 struct Stream {
     uint8_t refs;
     Drawable *current;
@@ -119,4 +122,6 @@ struct Stream {
     uint32_t input_fps;
 };
 
+void stream_agent_stats_print(StreamAgent *agent);
+
 #endif /* STREAM_H */
commit 1e4abdc15d83c605b020682979abc03dc4848f31
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Nov 10 11:37:55 2015 +0000

    worker: move stream definitions to a new stream.h file
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/Makefile.am b/server/Makefile.am
index 7216ab0..8ccf614 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -136,6 +136,7 @@ libspice_server_la_SOURCES =			\
 	spice-bitmap-utils.h			\
 	spice-bitmap-utils.c			\
 	utils.h					\
+	stream.h					\
 	$(NULL)
 
 if HAVE_GL
diff --git a/server/display-channel.h b/server/display-channel.h
index 055c2a7..7173c6e 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -54,6 +54,7 @@
 #include "spice_image_cache.h"
 #include "utils.h"
 #include "tree.h"
+#include "stream.h"
 
 typedef struct DisplayChannel DisplayChannel;
 typedef struct DisplayChannelClient DisplayChannelClient;
@@ -128,23 +129,6 @@ typedef struct {
     EncoderData data;
 } GlzData;
 
-typedef struct Stream Stream;
-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;
-};
-
 typedef struct DependItem {
     Drawable *drawable;
     RingItem ring_item;
@@ -179,48 +163,6 @@ struct Drawable {
     uint32_t process_commands_generation;
 };
 
-#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;
-
 struct DisplayChannelClient {
     CommonChannelClient common;
 
diff --git a/server/red_worker.c b/server/red_worker.c
index d73d616..b7428f1 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -58,6 +58,7 @@
 #include "common/generated_server_marshallers.h"
 
 #include "display-channel.h"
+#include "stream.h"
 
 #include "spice.h"
 #include "red_worker.h"
@@ -80,21 +81,6 @@
 
 #define DISPLAY_FREE_LIST_DEFAULT_SIZE 128
 
-#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 FPS_TEST_INTERVAL 1
 #define MAX_FPS 30
 
@@ -241,11 +227,6 @@ typedef struct SurfaceDestroyItem {
     PipeItem pipe_item;
 } SurfaceDestroyItem;
 
-typedef struct StreamActivateReportItem {
-    PipeItem pipe_item;
-    uint32_t stream_id;
-} StreamActivateReportItem;
-
 #define MAX_PIPE_SIZE 50
 
 #define WIDE_CLIENT_ACK_WINDOW 40
@@ -266,20 +247,6 @@ typedef struct ImageItem {
     uint8_t data[0];
 } ImageItem;
 
-enum {
-    STREAM_FRAME_NONE,
-    STREAM_FRAME_NATIVE,
-    STREAM_FRAME_CONTAINER,
-};
-
-typedef struct StreamClipItem {
-    PipeItem base;
-    int refs;
-    StreamAgent *stream_agent;
-    int clip_type;
-    SpiceClipRects *rects;
-} StreamClipItem;
-
 typedef struct {
     QuicUsrContext usr;
     EncoderData data;
diff --git a/server/stream.h b/server/stream.h
new file mode 100644
index 0000000..1587d4e
--- /dev/null
+++ b/server/stream.h
@@ -0,0 +1,122 @@
+/* -*- 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 "spice_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
+
+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;
+
+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;
+};
+
+#endif /* STREAM_H */


More information about the Spice-commits mailing list