Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> --- server/mjpeg_encoder.c | 53 +++++++++++++++++++++++++++++++++++++++++--------- server/mjpeg_encoder.h | 26 +++++++------------------ server/red_worker.c | 22 ++++++++------------- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c index 96b8f06..1c3ecff 100644 --- a/server/mjpeg_encoder.c +++ b/server/mjpeg_encoder.c @@ -692,11 +692,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; @@ -791,7 +802,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, @@ -823,7 +834,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; @@ -878,8 +889,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; @@ -915,6 +926,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; diff --git a/server/mjpeg_encoder.h b/server/mjpeg_encoder.h index 8e2af10..d070e70 100644 --- a/server/mjpeg_encoder.h +++ b/server/mjpeg_encoder.h @@ -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 diff --git a/server/red_worker.c b/server/red_worker.c index 6a77106..68485a5 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -8523,11 +8523,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); @@ -8537,19 +8538,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) { -- 2.6.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel