summaryrefslogtreecommitdiffstats
path: root/server/mjpeg_encoder.c
diff options
context:
space:
mode:
authorFrancois Gouget <fgouget@codeweavers.com>2015-10-14 17:31:01 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2015-10-30 15:35:47 +0100
commit3708bf9cf0315c2ab7299b5b93cc6d50fd8f1dae (patch)
treefbf7715c50eb59c4f788681e1f2c02b56b769d2e /server/mjpeg_encoder.c
parentfd451860df2df5a26d66a64c62b24afbe94c4e1b (diff)
downloadspice-3708bf9cf0315c2ab7299b5b93cc6d50fd8f1dae.tar.gz
spice-3708bf9cf0315c2ab7299b5b93cc6d50fd8f1dae.tar.xz
spice-3708bf9cf0315c2ab7299b5b93cc6d50fd8f1dae.zip
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>
Diffstat (limited to 'server/mjpeg_encoder.c')
-rw-r--r--server/mjpeg_encoder.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
index 3f8252ae..3cb2144d 100644
--- a/server/mjpeg_encoder.c
+++ b/server/mjpeg_encoder.c
@@ -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)
{