server: Hide the MJPEG encoder internals from red_worker.c

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
This commit is contained in:
Francois Gouget 2015-10-14 17:31:14 +02:00 committed by Christophe Fergeau
parent 3708bf9cf0
commit f2c8609985
3 changed files with 59 additions and 42 deletions

View File

@ -693,11 +693,22 @@ static void mjpeg_encoder_adjust_fps(MJpegEncoder *encoder, uint64_t now)
}
}
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)
/*
* dest must be either NULL or allocated by malloc, since it might be freed
* during the encoding, if its size is too small.
*
* return:
* MJPEG_ENCODER_FRAME_UNSUPPORTED : frame cannot be encoded
* MJPEG_ENCODER_FRAME_DROP : frame should be dropped. This value can only be returned
* if mjpeg rate control is active.
* MJPEG_ENCODER_FRAME_ENCODE_DONE : frame encoding started. Continue with
* mjpeg_encoder_encode_scanline.
*/
static 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)
{
uint32_t quality;
@ -792,7 +803,7 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder,
encoder->num_frames++;
encoder->avg_quality += quality;
return MJPEG_ENCODER_FRAME_ENCODE_START;
return MJPEG_ENCODER_FRAME_ENCODE_DONE;
}
static int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder,
@ -824,7 +835,7 @@ static int mjpeg_encoder_encode_scanline(MJpegEncoder *encoder,
return scanlines_written;
}
size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder)
static size_t mjpeg_encoder_end_frame(MJpegEncoder *encoder)
{
mem_destination_mgr *dest = (mem_destination_mgr *) encoder->cinfo.dest;
MJpegEncoderRateControl *rate_control = &encoder->rate_control;
@ -879,8 +890,8 @@ static inline uint8_t *get_image_line(SpiceChunks *chunks, size_t *offset,
return ret;
}
int mjpeg_encoder_encode_frame(MJpegEncoder *encoder, const SpiceRect *src,
const SpiceBitmap *image, int top_down)
static int encode_frame(MJpegEncoder *encoder, const SpiceRect *src,
const SpiceBitmap *image, int top_down)
{
SpiceChunks *chunks;
uint32_t image_stride;
@ -916,6 +927,30 @@ int mjpeg_encoder_encode_frame(MJpegEncoder *encoder, const SpiceRect *src,
return TRUE;
}
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)
{
int ret = mjpeg_encoder_start_frame(encoder, bitmap->format,
width, height, outbuf, outbuf_size,
frame_mm_time);
if (ret != MJPEG_ENCODER_FRAME_ENCODE_DONE) {
return ret;
}
if (!encode_frame(encoder, src, bitmap, top_down)) {
return MJPEG_ENCODER_FRAME_UNSUPPORTED;
}
*data_size = mjpeg_encoder_end_frame(encoder);
return MJPEG_ENCODER_FRAME_ENCODE_DONE;
}
static void mjpeg_encoder_quality_eval_stop(MJpegEncoder *encoder)
{
MJpegEncoderRateControl *rate_control = &encoder->rate_control;

View File

@ -24,7 +24,7 @@
enum {
MJPEG_ENCODER_FRAME_UNSUPPORTED = -1,
MJPEG_ENCODER_FRAME_DROP,
MJPEG_ENCODER_FRAME_ENCODE_START,
MJPEG_ENCODER_FRAME_ENCODE_DONE,
};
typedef struct MJpegEncoder MJpegEncoder;
@ -53,24 +53,12 @@ MJpegEncoder *mjpeg_encoder_new(uint64_t starting_bit_rate,
MJpegEncoderRateControlCbs *cbs, void *opaque);
void mjpeg_encoder_destroy(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.
*
* return:
* MJPEG_ENCODER_FRAME_UNSUPPORTED : frame cannot be encoded
* MJPEG_ENCODER_FRAME_DROP : frame should be dropped. This value can only be returned
* if mjpeg rate control is active.
* MJPEG_ENCODER_FRAME_ENCODE_START: frame encoding started. Continue with
* mjpeg_encoder_encode_scanline.
*/
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_frame(MJpegEncoder *encoder, const SpiceRect *src,
const SpiceBitmap *image, int top_down);
size_t mjpeg_encoder_end_frame(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

View File

@ -7759,11 +7759,12 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
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,
&dcc->send_data.stream_outbuf,
&outbuf_size,
frame_mm_time);
ret = mjpeg_encoder_encode_frame(agent->mjpeg_encoder,
&image->u.bitmap, width, height,
&drawable->red_drawable->u.copy.src_area,
stream->top_down, frame_mm_time,
&dcc->send_data.stream_outbuf,
&outbuf_size, &n);
switch (ret) {
case MJPEG_ENCODER_FRAME_DROP:
spice_assert(dcc->use_mjpeg_encoder_rate_control);
@ -7773,19 +7774,12 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
return TRUE;
case MJPEG_ENCODER_FRAME_UNSUPPORTED:
return FALSE;
case MJPEG_ENCODER_FRAME_ENCODE_START:
case MJPEG_ENCODER_FRAME_ENCODE_DONE:
break;
default:
spice_error("bad return value (%d) from mjpeg_encoder_start_frame", ret);
spice_error("bad return value (%d) from mjpeg_encoder_encode_frame", ret);
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;
if (!drawable->sized_stream) {