diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-04-08 17:09:32 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-04-08 17:09:32 +0200 |
commit | de4306af331f5a68c28949c5cfed60adea24f753 (patch) | |
tree | 47cb5aa82829eba5b90a6f2d6449e8a8e69c2e2c /server/mjpeg_encoder.c | |
parent | 18485cef06283c17ddd98fd5411b71bcb64201a3 (diff) | |
download | spice-de4306af331f5a68c28949c5cfed60adea24f753.tar.gz spice-de4306af331f5a68c28949c5cfed60adea24f753.tar.xz spice-de4306af331f5a68c28949c5cfed60adea24f753.zip |
Initialize _kill_mark so we don't get spurious valgrind warnings
Diffstat (limited to 'server/mjpeg_encoder.c')
-rw-r--r-- | server/mjpeg_encoder.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c new file mode 100644 index 00000000..b0ae49f6 --- /dev/null +++ b/server/mjpeg_encoder.c @@ -0,0 +1,125 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "red_common.h" +#include "mjpeg_encoder.h" +#include <jpeglib.h> + +struct MJpegEncoder { + int width; + int height; + int stride; + uint8_t *frame; + int first_frame; + int quality; + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; +}; + +MJpegEncoder *mjpeg_encoder_new(int width, int height) +{ + MJpegEncoder *enc; + + enc = spice_new0(MJpegEncoder, 1); + + enc->first_frame = TRUE; + enc->width = width; + enc->height = height; + enc->stride = width * 3; + enc->quality = 70; + if (enc->stride < width) { + abort(); + } + enc->frame = spice_malloc_n(enc->stride, height); + + enc->cinfo.err = jpeg_std_error(&enc->jerr); + + jpeg_create_compress(&enc->cinfo); + + return enc; +} + +void mjpeg_encoder_destroy(MJpegEncoder *encoder) +{ + jpeg_destroy_compress(&encoder->cinfo); + free(encoder->frame); + free(encoder); +} + +uint8_t *mjpeg_encoder_get_frame(MJpegEncoder *encoder) +{ + return encoder->frame; +} +size_t mjpeg_encoder_get_frame_stride(MJpegEncoder *encoder) +{ + return encoder->stride; +} + +void init_destination(j_compress_ptr cinfo) +{ +} + +boolean empty_output_buffer(j_compress_ptr cinfo) +{ + return FALSE; +} + +void term_destination(j_compress_ptr cinfo) +{ +} + +int mjpeg_encoder_encode_frame(MJpegEncoder *encoder, + uint8_t *buffer, size_t buffer_len) +{ + struct jpeg_destination_mgr destmgr; + uint8_t *frame; + int n; + + destmgr.next_output_byte = buffer; + destmgr.free_in_buffer = buffer_len; + destmgr.init_destination = init_destination; + destmgr.empty_output_buffer = empty_output_buffer; + destmgr.term_destination = term_destination; + + encoder->cinfo.dest = &destmgr; + + encoder->cinfo.image_width = encoder->width; + encoder->cinfo.image_height = encoder->height; + encoder->cinfo.input_components = 3; + encoder->cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&encoder->cinfo); + jpeg_set_quality(&encoder->cinfo, encoder->quality, TRUE); + jpeg_start_compress(&encoder->cinfo, encoder->first_frame); + + frame = encoder->frame; + while (encoder->cinfo.next_scanline < encoder->cinfo.image_height) { + n = jpeg_write_scanlines(&encoder->cinfo, &frame, 1); + if (n == 0) { /* Not enough space */ + jpeg_abort_compress(&encoder->cinfo); + return 0; + } + frame += encoder->stride; + } + + jpeg_finish_compress(&encoder->cinfo); + + encoder->first_frame = FALSE; + return destmgr.next_output_byte - buffer; +} |