1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009 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 _H_MJPEG_ENCODER
#define _H_MJPEG_ENCODER
#include "red-common.h"
enum {
MJPEG_ENCODER_FRAME_UNSUPPORTED = -1,
MJPEG_ENCODER_FRAME_DROP,
MJPEG_ENCODER_FRAME_ENCODE_DONE,
};
typedef struct MJpegEncoder MJpegEncoder;
/*
* Callbacks required for controling and adjusting
* the stream bit rate:
* @opaque: a pointer to be passed to the rate control callbacks.
* get_roundtrip_ms: roundtrip time in milliseconds
* get_source_fps: the input frame rate (#frames per second), i.e.,
* the rate of frames arriving from the guest to spice-server,
* before any drops.
*/
typedef struct MJpegEncoderRateControlCbs {
void *opaque;
uint32_t (*get_roundtrip_ms)(void *opaque);
uint32_t (*get_source_fps)(void *opaque);
void (*update_client_playback_delay)(void *opaque, uint32_t delay_ms);
} MJpegEncoderRateControlCbs;
typedef struct MJpegEncoderStats {
uint64_t starting_bit_rate;
uint64_t cur_bit_rate;
double avg_quality;
} MJpegEncoderStats;
MJpegEncoder *mjpeg_encoder_new(uint64_t starting_bit_rate,
MJpegEncoderRateControlCbs *cbs);
void mjpeg_encoder_destroy(MJpegEncoder *encoder);
int mjpeg_encoder_encode_frame(MJpegEncoder *encoder,
const SpiceBitmap *bitmap, int width, int height,
const SpiceRect *src,
int top_down, uint32_t frame_mm_time,
uint8_t **outbuf, size_t *outbuf_size,
int *data_size);
/*
* bit rate control
*/
/*
* Data that should be periodically obtained from the client. The report contains:
* num_frames : the number of frames that reached the client during the time
* the report is referring to.
* num_drops : the part of the above frames that was dropped by the client due to
* late arrival time.
* start_frame_mm_time: the mm_time of the first frame included in the report
* end_frame_mm_time : the mm_time of the last_frame included in the report
* end_frame_delay : (end_frame_mm_time - client_mm_time)
* audio delay : the latency of the audio playback.
* If there is no audio playback, set it to MAX_UINT.
*
*/
void mjpeg_encoder_client_stream_report(MJpegEncoder *encoder,
uint32_t num_frames,
uint32_t num_drops,
uint32_t start_frame_mm_time,
uint32_t end_frame_mm_time,
int32_t end_frame_delay,
uint32_t audio_delay);
/*
* Notify the encoder each time a frame is dropped due to pipe
* congestion.
* We can deduce the client state by the frame dropping rate in the server.
* Monitoring the frame drops can help in fine tuning the playback parameters
* when the client reports are delayed.
*/
void mjpeg_encoder_notify_server_frame_drop(MJpegEncoder *encoder);
uint64_t mjpeg_encoder_get_bit_rate(MJpegEncoder *encoder);
void mjpeg_encoder_get_stats(MJpegEncoder *encoder, MJpegEncoderStats *stats);
#endif
|