mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-08 01:42:06 +00:00
server: Move the MJPEG encoder functions to mjpeg_encoder.c
Note that this requires some adjustments to the encode_frame() parameters to avoid red_worker-specific types. Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
This commit is contained in:
parent
fd451860df
commit
3708bf9cf0
@ -192,7 +192,7 @@ void mjpeg_encoder_destroy(MJpegEncoder *encoder)
|
||||
free(encoder);
|
||||
}
|
||||
|
||||
uint8_t mjpeg_encoder_get_bytes_per_pixel(MJpegEncoder *encoder)
|
||||
static uint8_t mjpeg_encoder_get_bytes_per_pixel(MJpegEncoder *encoder)
|
||||
{
|
||||
return encoder->bytes_per_pixel;
|
||||
}
|
||||
@ -693,7 +693,8 @@ static void mjpeg_encoder_adjust_fps(MJpegEncoder *encoder, uint64_t now)
|
||||
}
|
||||
}
|
||||
|
||||
int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
|
||||
int mjpeg_encoder_start_frame(MJpegEncoder *encoder,
|
||||
SpiceBitmapFmt format,
|
||||
int width, int height,
|
||||
uint8_t **dest, size_t *dest_len,
|
||||
uint32_t frame_mm_time)
|
||||
@ -794,8 +795,9 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
|
||||
return MJPEG_ENCODER_FRAME_ENCODE_START;
|
||||
}
|
||||
|
||||
int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder, uint8_t *src_pixels,
|
||||
size_t image_width)
|
||||
static int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder,
|
||||
uint8_t *src_pixels,
|
||||
size_t image_width)
|
||||
{
|
||||
unsigned int scanlines_written;
|
||||
uint8_t *row;
|
||||
@ -851,6 +853,69 @@ size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder)
|
||||
return encoder->rate_control.last_enc_size;
|
||||
}
|
||||
|
||||
static inline uint8_t *get_image_line(SpiceChunks *chunks, size_t *offset,
|
||||
int *chunk_nr, int stride)
|
||||
{
|
||||
uint8_t *ret;
|
||||
SpiceChunk *chunk;
|
||||
|
||||
chunk = &chunks->chunk[*chunk_nr];
|
||||
|
||||
if (*offset == chunk->len) {
|
||||
if (*chunk_nr == chunks->num_chunks - 1) {
|
||||
return NULL; /* Last chunk */
|
||||
}
|
||||
*offset = 0;
|
||||
(*chunk_nr)++;
|
||||
chunk = &chunks->chunk[*chunk_nr];
|
||||
}
|
||||
|
||||
if (chunk->len - *offset < stride) {
|
||||
spice_warning("bad chunk alignment");
|
||||
return NULL;
|
||||
}
|
||||
ret = chunk->data + *offset;
|
||||
*offset += stride;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mjpeg_encoder_encode_frame(MJpegEncoder *encoder, const SpiceRect *src,
|
||||
const SpiceBitmap *image, int top_down)
|
||||
{
|
||||
SpiceChunks *chunks;
|
||||
uint32_t image_stride;
|
||||
size_t offset;
|
||||
int i, chunk;
|
||||
|
||||
chunks = image->data;
|
||||
offset = 0;
|
||||
chunk = 0;
|
||||
image_stride = image->stride;
|
||||
|
||||
const int skip_lines = top_down ? src->top : image->y - (src->bottom - 0);
|
||||
for (i = 0; i < skip_lines; i++) {
|
||||
get_image_line(chunks, &offset, &chunk, image_stride);
|
||||
}
|
||||
|
||||
const unsigned int stream_height = src->bottom - src->top;
|
||||
const unsigned int stream_width = src->right - src->left;
|
||||
|
||||
for (i = 0; i < stream_height; i++) {
|
||||
uint8_t *src_line = get_image_line(chunks, &offset, &chunk, image_stride);
|
||||
|
||||
if (!src_line) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src_line += src->left * mjpeg_encoder_get_bytes_per_pixel(encoder);
|
||||
if (mjpeg_encoder_encode_scanline(encoder, src_line, stream_width) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void mjpeg_encoder_quality_eval_stop(MJpegEncoder *encoder)
|
||||
{
|
||||
MJpegEncoderRateControl *rate_control = &encoder->rate_control;
|
||||
@ -1021,6 +1086,7 @@ static void mjpeg_encoder_increase_bit_rate(MJpegEncoder *encoder)
|
||||
rate_control->quality_id,
|
||||
rate_control->fps);
|
||||
}
|
||||
|
||||
static void mjpeg_encoder_handle_positive_client_stream_report(MJpegEncoder *encoder,
|
||||
uint32_t report_start_frame_mm_time)
|
||||
{
|
||||
|
||||
@ -53,8 +53,6 @@ MJpegEncoder *mjpeg_encoder_new(uint64_t starting_bit_rate,
|
||||
MJpegEncoderRateControlCbs *cbs, void *opaque);
|
||||
void mjpeg_encoder_destroy(MJpegEncoder *encoder);
|
||||
|
||||
uint8_t mjpeg_encoder_get_bytes_per_pixel(MJpegEncoder *encoder);
|
||||
|
||||
/*
|
||||
* dest must be either NULL or allocated by malloc, since it might be freed
|
||||
* during the encoding, if its size is too small.
|
||||
@ -70,8 +68,8 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
|
||||
int width, int height,
|
||||
uint8_t **dest, size_t *dest_len,
|
||||
uint32_t frame_mm_time);
|
||||
int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder, uint8_t *src_pixels,
|
||||
size_t image_width);
|
||||
int mjpeg_encoder_encode_frame(MJpegEncoder *encoder, const SpiceRect *src,
|
||||
const SpiceBitmap *image, int top_down);
|
||||
size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder);
|
||||
|
||||
/*
|
||||
|
||||
@ -7699,69 +7699,6 @@ static inline void display_begin_send_message(RedChannelClient *rcc)
|
||||
red_channel_client_begin_send_message(rcc);
|
||||
}
|
||||
|
||||
static inline uint8_t *red_get_image_line(SpiceChunks *chunks, size_t *offset,
|
||||
int *chunk_nr, int stride)
|
||||
{
|
||||
uint8_t *ret;
|
||||
SpiceChunk *chunk;
|
||||
|
||||
chunk = &chunks->chunk[*chunk_nr];
|
||||
|
||||
if (*offset == chunk->len) {
|
||||
if (*chunk_nr == chunks->num_chunks - 1) {
|
||||
return NULL; /* Last chunk */
|
||||
}
|
||||
*offset = 0;
|
||||
(*chunk_nr)++;
|
||||
chunk = &chunks->chunk[*chunk_nr];
|
||||
}
|
||||
|
||||
if (chunk->len - *offset < stride) {
|
||||
spice_warning("bad chunk alignment");
|
||||
return NULL;
|
||||
}
|
||||
ret = chunk->data + *offset;
|
||||
*offset += stride;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encode_frame(DisplayChannelClient *dcc, const SpiceRect *src,
|
||||
const SpiceBitmap *image, Stream *stream)
|
||||
{
|
||||
SpiceChunks *chunks;
|
||||
uint32_t image_stride;
|
||||
size_t offset;
|
||||
int i, chunk;
|
||||
StreamAgent *agent = &dcc->stream_agents[stream - dcc->common.worker->streams_buf];
|
||||
|
||||
chunks = image->data;
|
||||
offset = 0;
|
||||
chunk = 0;
|
||||
image_stride = image->stride;
|
||||
|
||||
const int skip_lines = stream->top_down ? src->top : image->y - (src->bottom - 0);
|
||||
for (i = 0; i < skip_lines; i++) {
|
||||
red_get_image_line(chunks, &offset, &chunk, image_stride);
|
||||
}
|
||||
|
||||
const unsigned int stream_height = src->bottom - src->top;
|
||||
const unsigned int stream_width = src->right - src->left;
|
||||
|
||||
for (i = 0; i < stream_height; i++) {
|
||||
uint8_t *src_line = red_get_image_line(chunks, &offset, &chunk, image_stride);
|
||||
|
||||
if (!src_line) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src_line += src->left * mjpeg_encoder_get_bytes_per_pixel(agent->mjpeg_encoder);
|
||||
if (mjpeg_encoder_encode_scanline(agent->mjpeg_encoder, src_line, stream_width) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline int red_marshall_stream_data(RedChannelClient *rcc,
|
||||
SpiceMarshaller *base_marshaller, Drawable *drawable)
|
||||
{
|
||||
@ -7820,6 +7757,7 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
|
||||
frame_mm_time = drawable->red_drawable->mm_time ?
|
||||
drawable->red_drawable->mm_time :
|
||||
reds_get_mm_time();
|
||||
|
||||
outbuf_size = dcc->send_data.stream_outbuf_size;
|
||||
ret = mjpeg_encoder_start_frame(agent->mjpeg_encoder, image->u.bitmap.format,
|
||||
width, height,
|
||||
@ -7842,10 +7780,11 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!encode_frame(dcc, &drawable->red_drawable->u.copy.src_area,
|
||||
&image->u.bitmap, stream)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!mjpeg_encoder_encode_frame(agent->mjpeg_encoder,
|
||||
&drawable->red_drawable->u.copy.src_area,
|
||||
&image->u.bitmap, stream->top_down)) {
|
||||
return FALSE;
|
||||
}
|
||||
n = mjpeg_encoder_end_frame(agent->mjpeg_encoder);
|
||||
dcc->send_data.stream_outbuf_size = outbuf_size;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user