summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/Makefile.am2
-rw-r--r--client/display_channel.cpp175
-rw-r--r--client/mjpeg_decoder.cpp236
-rw-r--r--client/mjpeg_decoder.h72
-rw-r--r--client/windows/redc.vcproj16
-rw-r--r--client/x11/Makefile.am16
-rw-r--r--configure.ac13
7 files changed, 367 insertions, 163 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 887c7b5a..81ad6dbf 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -49,6 +49,8 @@ RED_COMMON_SRCS = \
mem.cpp \
menu.cpp \
menu.h \
+ mjpeg_decoder.h \
+ mjpeg_decoder.cpp \
pixels_source.h \
platform.h \
playback_channel.cpp \
diff --git a/client/display_channel.cpp b/client/display_channel.cpp
index d63726cd..6427ae4d 100644
--- a/client/display_channel.cpp
+++ b/client/display_channel.cpp
@@ -38,11 +38,9 @@
#include "red_gdi_canvas.h"
#endif
#include "platform_utils.h"
-#include "ffmpeg_inc.h"
#include "inputs_channel.h"
#include "cursor_channel.h"
-
-static Mutex avcodec_mutex;
+#include "mjpeg_decoder.h"
class CreatePrimarySurfaceEvent: public SyncEvent {
public:
@@ -144,85 +142,6 @@ private:
AutoRef<RedScreen> _screen;
};
-#define CLIP_ARRAY_SIZE 1500
-#define CLIP_ARRAY_SHIFT 500
-
-static uint8_t clip_array[CLIP_ARRAY_SIZE];
-static uint8_t *clip_zero = &clip_array[CLIP_ARRAY_SHIFT];
-
-static void init_clip_array()
-{
- int i;
- for (i = 0; i < CLIP_ARRAY_SHIFT; i++) {
- clip_array[i] = 0;
- }
-
- for (i = CLIP_ARRAY_SHIFT + 256; i < CLIP_ARRAY_SIZE; i++) {
- clip_array[i] = 0xff;
- }
-
- for (i = 0; i < 256; i++) {
- clip_zero[i] = i;
- }
-}
-
-#define CLIP(val) clip_zero[(int)(val)]
-
-#define R(pixel) (((uint8_t*)(pixel))[0])
-#define G(pixel) (((uint8_t*)(pixel))[1])
-#define B(pixel) (((uint8_t*)(pixel))[2])
-
-#define YUV_TO_RGB(pixel, y, u , v) { \
- int Y = (y) - 16; \
- int U = (u) - 128; \
- int V = (v) - 128; \
- R(pixel) = CLIP((298 * Y + 409 * V + 128) >> 8); \
- G(pixel) = CLIP((298 * Y - 100 * U - 208 * V + 128) >> 8); \
- B(pixel) = CLIP((298 * Y + 516 * U + 128) >> 8); \
-}
-
-static inline void yuv420_to_rgb(AVFrame* frame, uint8_t* data, uint32_t width, uint32_t height,
- int stride, int top_down)
-{
- ASSERT(width % 2 == 0);
- ASSERT(height % 2 == 0);
-
- /* turning it to be down to top */
- if (top_down) {
- data += stride * (height - 1);
- stride = -stride;
- }
-
- // B = 1.164(Y - 16) + 2.018(U - 128)
- // G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
- // R = 1.164(Y - 16) + 1.596(V - 128)
-
- uint8_t* y_line = frame->data[0];
- uint8_t* u = frame->data[1];
- uint8_t* v = frame->data[2];
-
- uint32_t y_stride = frame->linesize[0];
- uint32_t u_stride = frame->linesize[1];
- uint32_t v_stride = frame->linesize[2];
-
- for (unsigned int i = 0; i < height / 2; i++) {
- uint8_t* now = data;
- uint8_t* y = y_line;
-
- for (unsigned int j = 0; j < width / 2; j++) {
- YUV_TO_RGB(now, *y, u[j], v[j]);
- YUV_TO_RGB(now + sizeof(uint32_t), *(y + 1), u[j], v[j]);
- YUV_TO_RGB(now + stride, *(y + y_stride), u[j], v[j]);
- YUV_TO_RGB(now + stride + sizeof(uint32_t), *(y + y_stride + 1), u[j], v[j]);
- y += 2;
- now += 2 * sizeof(uint32_t);
- }
- data += stride * 2;
- y_line += y_stride * 2;
- u += u_stride;
- v += v_stride;
- }
-}
#define MAX_VIDEO_FRAMES 30
#define MAX_OVER 15
@@ -243,8 +162,6 @@ public:
void handle_update_mark(uint64_t update_mark);
uint32_t handle_timer_update(uint32_t now);
- static void init();
-
private:
void free_frame(uint32_t frame_index);
void release_all_bufs();
@@ -259,8 +176,7 @@ private:
RedClient& _client;
Canvas& _canvas;
DisplayChannel& _channel;
- AVCodecContext* _ctx;
- AVFrame* _frame;
+ MJpegDecoder *_mjpeg_decoder;
int _stream_width;
int _stream_height;
int _stride;
@@ -339,8 +255,7 @@ VideoStream::VideoStream(RedClient& client, Canvas& canvas, DisplayChannel& chan
: _client (client)
, _canvas (canvas)
, _channel (channel)
- , _ctx (NULL)
- , _frame (NULL)
+ , _mjpeg_decoder (NULL)
, _stream_width (stream_width)
, _stream_height (stream_height)
, _stride (stream_width * sizeof(uint32_t))
@@ -354,34 +269,13 @@ VideoStream::VideoStream(RedClient& client, Canvas& canvas, DisplayChannel& chan
, _update_time (0)
, next (NULL)
{
- AVCodecContext* ctx = NULL;
- AVCodec* codec;
- AVFrame* frame = NULL;
-
- enum CodecID type;
-
memset(_frames, 0, sizeof(_frames));
region_init(&_clip_region);
- switch (codec_type) {
- case SPICE_VIDEO_CODEC_TYPE_MJPEG:
- type = CODEC_ID_MJPEG;
- break;
- default:
- THROW("invalid vide codec type %u", codec_type);
+ if (codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG) {
+ THROW("invalid vide codec type %u", codec_type);
}
- if (!(codec = avcodec_find_decoder(type))) {
- THROW("can't find codec %u", type);
- }
-
- if (!(ctx = avcodec_alloc_context())) {
- THROW("alloc codec ctx failed");
- }
try {
- if (!(frame = avcodec_alloc_frame())) {
- THROW("alloc frame failed");
- }
-
#ifdef WIN32
if (!create_bitmap(&_dc, &_prev_bitmap, &_uncompressed_data, &_stride,
stream_width, stream_height)) {
@@ -393,35 +287,37 @@ VideoStream::VideoStream(RedClient& client, Canvas& canvas, DisplayChannel& chan
_pixmap.width = src_width;
_pixmap.height = src_height;
+ _mjpeg_decoder = new MJpegDecoder(stream_width, stream_height, _stride, _uncompressed_data);
+
#ifdef WIN32
SetViewportOrgEx(_dc, 0, stream_height - src_height, NULL);
#endif
- _pixmap.data = _uncompressed_data + _stride * (src_height - 1);
- _pixmap.stride = -_stride;
+
+ if (_top_down) {
+ _pixmap.data = _uncompressed_data;
+ _pixmap.stride = _stride;
+ } else {
+ _pixmap.data = _uncompressed_data + _stride * (src_height - 1);
+ _pixmap.stride = -_stride;
+ }
set_clip(clip_type, num_clip_rects, clip_rects);
- Lock lock(avcodec_mutex);
- if (avcodec_open(ctx, codec) < 0) {
- THROW("open avcodec failed");
- }
} catch (...) {
- av_free(frame);
- av_free(ctx);
+ if (_mjpeg_decoder) {
+ delete _mjpeg_decoder;
+ _mjpeg_decoder = NULL;
+ }
release_all_bufs();
throw;
}
- _frame = frame;
- _ctx = ctx;
}
VideoStream::~VideoStream()
{
- if (_ctx) {
- Lock lock(avcodec_mutex);
- avcodec_close(_ctx);
- av_free(_ctx);
- av_free(_frame);
+ if (_mjpeg_decoder) {
+ delete _mjpeg_decoder;
+ _mjpeg_decoder = NULL;
}
release_all_bufs();
region_destroy(&_clip_region);
@@ -493,20 +389,8 @@ void VideoStream::maintenance()
uint8_t* data = tail->compressed_data;
uint32_t length = tail->compressed_data_size;
int got_picture = 0;
- while (length > 0) {
- int n = avcodec_decode_video(_ctx, _frame, &got_picture, data, length);
- if (n < 0) {
- THROW("decoding eror");
- }
- if (got_picture) {
- yuv420_to_rgb(_frame, _uncompressed_data, _stream_width, _stream_height, _stride,
- _top_down);
- ASSERT(length - n == 0);
- break;
- }
- length -= n;
- data += n;
- }
+
+ got_picture =_mjpeg_decoder->decode_data(data, length);
if (got_picture) {
#ifdef WIN32
_canvas.put_image(_dc, _pixmap, _dest, _clip);
@@ -560,9 +444,6 @@ uint32_t VideoStream::alloc_frame_slot()
void VideoStream::push_data(uint32_t mm_time, uint32_t length, uint8_t* data, uint32_t ped_size)
{
- if (ped_size < FF_INPUT_BUFFER_PADDING_SIZE) {
- THROW("insufficieant pedding");
- }
maintenance();
uint32_t frame_slot = alloc_frame_slot();
_frames[frame_slot].compressed_data = new uint8_t[length];
@@ -588,18 +469,10 @@ void VideoStream::set_clip(int type, uint32_t num_clip_rects, SpiceRect* clip_re
_clip = &_clip_region;
}
-void VideoStream::init()
-{
- avcodec_init();
- avcodec_register_all();
- init_clip_array();
-}
-
class AutoVStreamInit {
public:
AutoVStreamInit()
{
- VideoStream::init();
}
};
diff --git a/client/mjpeg_decoder.cpp b/client/mjpeg_decoder.cpp
new file mode 100644
index 00000000..21804fb4
--- /dev/null
+++ b/client/mjpeg_decoder.cpp
@@ -0,0 +1,236 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 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/>.
+*/
+
+#ifndef WIN32
+#include "config.h"
+#endif
+
+#include "common.h"
+#include "debug.h"
+#include "utils.h"
+#include "mjpeg_decoder.h"
+
+enum {
+ STATE_READ_HEADER,
+ STATE_START_DECOMPRESS,
+ STATE_READ_SCANLINES,
+ STATE_FINISH_DECOMPRESS
+};
+
+extern "C" {
+
+ static void init_source(j_decompress_ptr cinfo)
+ {
+ }
+
+ static boolean fill_input_buffer(j_decompress_ptr cinfo)
+ {
+ return FALSE;
+ }
+
+ void mjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+ {
+ MJpegDecoder *decoder = (MJpegDecoder *)cinfo;
+ if (num_bytes > 0) {
+ if (cinfo->src->bytes_in_buffer >= (size_t)num_bytes) {
+ cinfo->src->next_input_byte += (size_t) num_bytes;
+ cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
+ } else {
+ decoder->_extra_skip = num_bytes - cinfo->src->bytes_in_buffer;
+ cinfo->src->bytes_in_buffer = 0;
+ }
+ }
+ }
+
+ static void term_source (j_decompress_ptr cinfo)
+ {
+ return;
+ }
+}
+
+MJpegDecoder::MJpegDecoder(int width, int height,
+ int stride,
+ uint8_t *frame) :
+ _data(NULL)
+ , _data_size(0)
+ , _data_start(0)
+ , _data_end(0)
+ , _extra_skip(0)
+ , _width(width)
+ , _height(height)
+ , _stride(stride)
+ , _frame(frame)
+ , _y(0)
+ , _state(0)
+{
+ memset(&_cinfo, 0, sizeof(_cinfo));
+ _cinfo.err = jpeg_std_error (&_jerr);
+ jpeg_create_decompress (&_cinfo);
+
+ _cinfo.src = &_jsrc;
+ _cinfo.src->init_source = init_source;
+ _cinfo.src->fill_input_buffer = fill_input_buffer;
+ _cinfo.src->skip_input_data = mjpeg_skip_input_data;
+ _cinfo.src->resync_to_restart = jpeg_resync_to_restart;
+ _cinfo.src->term_source = term_source;
+
+ _scanline = new uint8_t[width * 3];
+}
+
+MJpegDecoder::~MJpegDecoder()
+{
+ delete [] _scanline;
+ if (_data) {
+ delete [] _data;
+ }
+}
+
+void MJpegDecoder::convert_scanline(void)
+{
+ uint32_t *row;
+ uint32_t c;
+ uint8_t *s;
+ int x;
+
+ ASSERT(_width % 2 == 0);
+ ASSERT(_height % 2 == 0);
+
+ row = (uint32_t *)(_frame + _y * _stride);
+ s = _scanline;
+ for (x = 0; x < _width; x++) {
+ /* This switches the order of red and blue.
+ This is not accidental, but for backwards
+ compatibility, since a bug in the old
+ ffmpeg-using mjpeg code got these switched
+ due to endianness issues. */
+ c = s[0] | s[1] << 8 | s[2] << 16;
+ s += 3;
+ *row++ = c;
+ }
+}
+
+bool MJpegDecoder::decode_data(uint8_t *data, size_t length)
+{
+ uint8_t *new_data;
+ size_t data_len;
+ int res;
+ bool got_picture;
+
+ got_picture = false;
+
+ if (_extra_skip > 0) {
+ if (_extra_skip >= length) {
+ _extra_skip -= length;
+ return false;
+ } else {
+ data += _extra_skip;
+ length -= _extra_skip;
+ _extra_skip = 0;
+ }
+ }
+
+ if (_data_size - _data_end < length) {
+ /* Can't fit in tail */
+
+ data_len = _data_end - _data_start;
+ if (_data_size - data_len < length) {
+ /* Can't fit at all, grow a bit */
+ _data_size = _data_size + length * 2;
+ new_data = new uint8_t[_data_size];
+ memcpy (new_data, _data + _data_start, data_len);
+ delete [] _data;
+ _data = new_data;
+ } else {
+ /* Just needs to compact */
+ memmove (_data, _data + _data_start, data_len);
+ }
+ _data_start = 0;
+ _data_end = data_len;
+ }
+
+ memcpy (_data + _data_end, data, length);
+ _data_end += length;
+
+ _jsrc.next_input_byte = _data + _data_start;
+ _jsrc.bytes_in_buffer = _data_end - _data_start;
+
+ switch (_state) {
+ case STATE_READ_HEADER:
+ res = jpeg_read_header(&_cinfo, TRUE);
+ if (res == JPEG_SUSPENDED) {
+ break;
+ }
+
+ _cinfo.do_fancy_upsampling = FALSE;
+ _cinfo.do_block_smoothing = FALSE;
+ _cinfo.out_color_space = JCS_RGB;
+
+ PANIC_ON(_cinfo.image_width != _width);
+ PANIC_ON(_cinfo.image_height != _height);
+
+ _state = STATE_START_DECOMPRESS;
+
+ /* fall through */
+ case STATE_START_DECOMPRESS:
+ res = jpeg_start_decompress (&_cinfo);
+
+ if (!res) {
+ break;
+ }
+
+ _state = STATE_READ_SCANLINES;
+
+ /* fall through */
+ case STATE_READ_SCANLINES:
+ res = 0;
+ while (_y < _height) {
+ res = jpeg_read_scanlines(&_cinfo, &_scanline, 1);
+
+ if (res == 0) {
+ break;
+ }
+
+ convert_scanline();
+ _y++;
+ }
+ if (res == 0) {
+ break;
+ }
+
+ _state = STATE_FINISH_DECOMPRESS;
+
+ /* fall through */
+ case STATE_FINISH_DECOMPRESS:
+ res = jpeg_finish_decompress (&_cinfo);
+
+ if (!res) {
+ break;
+ }
+
+ _y = 0;
+ _state = STATE_READ_HEADER;
+ got_picture = true;
+
+ break;
+ }
+
+ _data_start = _jsrc.next_input_byte - _data;
+ _data_end = _data_start + _jsrc.bytes_in_buffer;
+
+ return got_picture;
+}
diff --git a/client/mjpeg_decoder.h b/client/mjpeg_decoder.h
new file mode 100644
index 00000000..f5176758
--- /dev/null
+++ b/client/mjpeg_decoder.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 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/>.
+*/
+
+#ifndef _H_MJPEG_DECODER
+#define _H_MJPEG_DECODER
+
+#include "common.h"
+
+#ifdef WIN32
+/* We need some hacks to avoid warnings from the jpeg headers */
+#define XMD_H
+#undef FAR
+#endif
+extern "C" {
+#include <jpeglib.h>
+}
+
+extern "C" {
+ void mjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
+}
+
+class MJpegDecoder {
+public:
+ MJpegDecoder(int width, int height, int stride,
+ uint8_t *frame);
+ ~MJpegDecoder();
+
+ bool decode_data(uint8_t *data, size_t length);
+
+private:
+
+ friend void mjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
+
+ void convert_scanline(void);
+
+ struct jpeg_decompress_struct _cinfo;
+ struct jpeg_error_mgr _jerr;
+ struct jpeg_source_mgr _jsrc;
+
+ uint8_t *_data;
+ size_t _data_size;
+ size_t _data_start;
+ size_t _data_end;
+ size_t _extra_skip;
+
+ int _width;
+ int _height;
+ int _stride;
+ uint8_t *_frame;
+
+ int _y;
+ uint8_t *_scanline;
+
+ int _state;
+};
+
+#endif
diff --git a/client/windows/redc.vcproj b/client/windows/redc.vcproj
index 18aca16f..ae941352 100644
--- a/client/windows/redc.vcproj
+++ b/client/windows/redc.vcproj
@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".;..;..\..\common;..\..\..\spice-protocol;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\ffmpeg&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
+ AdditionalIncludeDirectories=".;..;..\..\common;..\..\..\spice-protocol;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;CAIRO_CANVAS_ACCESS_TEST;CAIRO_CANVAS_CACHE;RED_DEBUG;CAIRO_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
MinimalRebuild="false"
BasicRuntimeChecks="3"
@@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="log4cppD.lib pixman-1D.lib libeay32MTd.lib ssleay32MTd.lib ws2_32.lib msimg32.lib winmm.lib avcodec-51.lib avutil-49.lib libcelt_0_5_1D.lib pthreadsD.lib version.lib CEGUIBase_Static_d.lib CEGUITGAImageCodec_Static_d.lib CEGUIExpatParser_Static_d.lib freetype235MT_D.lib libexpatMT_D.lib pcre_D.lib CEGUIFalagardWRBase_Static_d.lib"
+ AdditionalDependencies="log4cppD.lib pixman-1D.lib libeay32MTd.lib ssleay32MTd.lib ws2_32.lib msimg32.lib winmm.lib libcelt_0_5_1D.lib pthreadsD.lib version.lib CEGUIBase_Static_d.lib CEGUITGAImageCodec_Static_d.lib CEGUIExpatParser_Static_d.lib freetype235MT_D.lib libexpatMT_D.lib pcre_D.lib CEGUIFalagardWRBase_Static_d.lib libjpeg-static-mt-debug.lib"
OutputFile="$(OutDir)\spicec.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib&quot;"
@@ -124,7 +124,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".;..;..\..\..\spice-protocol;..\..\common;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\ffmpeg&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
+ AdditionalIncludeDirectories=".;..;..\..\..\spice-protocol;..\..\common;..\..\common\win;&quot;..\..\common\win\my_getopt-1.5&quot;;&quot;$(SPICE_LIBS)\include&quot;;&quot;$(SPICE_LIBS)\include\pixman-1&quot;;&quot;$(SPICE_LIBS)\include\CEGUI-0.6.2&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;CAIRO_CANVAS_ACCESS_TEST;CAIRO_CANVAS_CACHE;CAIRO_CANVAS_NO_CHUNKS;_WIN32_WINNT=0x0500;LOG4CPLUS_STATIC;USE_GLZ;PTW32_STATIC_LIB;CEGUI_STATIC"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@@ -144,7 +144,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="log4cpp.lib pixman-1.lib libeay32MT.lib ssleay32MT.lib ws2_32.lib msimg32.lib winmm.lib avcodec-51.lib avutil-49.lib libcelt_0_5_1.lib pthreads.lib version.lib CEGUIBase_Static.lib CEGUITGAImageCodec_Static.lib CEGUIExpatParser_Static.lib freetype235MT.lib libexpatMT.lib pcre.lib CEGUIFalagardWRBase_Static.lib"
+ AdditionalDependencies="log4cpp.lib pixman-1.lib libeay32MT.lib ssleay32MT.lib ws2_32.lib msimg32.lib winmm.lib libcelt_0_5_1.lib pthreads.lib version.lib CEGUIBase_Static.lib CEGUITGAImageCodec_Static.lib CEGUIExpatParser_Static.lib freetype235MT.lib libexpatMT.lib pcre.lib CEGUIFalagardWRBase_Static.lib libjpeg-static-mt.lib"
OutputFile="$(OutDir)\spicec.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib&quot;"
@@ -272,6 +272,10 @@
>
</File>
<File
+ RelativePath="..\mjpeg_decoder.cpp"
+ >
+ </File>
+ <File
RelativePath="..\monitor.cpp"
>
</File>
@@ -524,6 +528,10 @@
>
</File>
<File
+ RelativePath="..\mjpeg_decoder.h"
+ >
+ </File>
+ <File
RelativePath="..\monitor.h"
>
</File>
diff --git a/client/x11/Makefile.am b/client/x11/Makefile.am
index ee92b332..e5a3b773 100644
--- a/client/x11/Makefile.am
+++ b/client/x11/Makefile.am
@@ -12,7 +12,7 @@ INCLUDES = \
-DUSE_GLZ \
-DUSE_OGL \
-D__STDC_LIMIT_MACROS \
- -I. \
+ -I. \
-I.. \
-I$(COMMON_DIR) \
-I$(COMMON_DIR)/linux \
@@ -20,7 +20,6 @@ INCLUDES = \
$(PROTOCOL_CFLAGS) \
$(GL_CFLAGS) \
$(ALSA_CFLAGS) \
- $(FFMPEG_CFLAGS) \
$(PIXMAN_CFLAGS) \
$(LOG4CPP_CFLAGS) \
$(CELT051_CFLAGS) \
@@ -33,7 +32,7 @@ INCLUDES = \
$(NULL)
-RED_COMMON_SRCS = \
+RED_COMMON_SRCS = \
$(CLIENT_DIR)/application.cpp \
$(CLIENT_DIR)/application.h \
$(CLIENT_DIR)/audio_channels.h \
@@ -77,6 +76,8 @@ RED_COMMON_SRCS = \
$(CLIENT_DIR)/mem.cpp \
$(CLIENT_DIR)/menu.cpp \
$(CLIENT_DIR)/menu.h \
+ $(CLIENT_DIR)/mjpeg_decoder.h \
+ $(CLIENT_DIR)/mjpeg_decoder.cpp \
$(CLIENT_DIR)/pixels_source.h \
$(CLIENT_DIR)/pixman_utils.cpp \
$(CLIENT_DIR)/platform.h \
@@ -111,9 +112,9 @@ RED_COMMON_SRCS = \
$(CLIENT_DIR)/tunnel_channel.h \
$(CLIENT_DIR)/utils.cpp \
$(CLIENT_DIR)/utils.h \
- $(CLIENT_DIR)/icon.h \
- $(CLIENT_DIR)/gui/softrenderer.h \
- $(CLIENT_DIR)/gui/softrenderer.cpp \
+ $(CLIENT_DIR)/icon.h \
+ $(CLIENT_DIR)/gui/softrenderer.h \
+ $(CLIENT_DIR)/gui/softrenderer.cpp \
$(CLIENT_DIR)/gui/softtexture.h \
$(CLIENT_DIR)/gui/softtexture.cpp \
$(CLIENT_DIR)/gui/resource_provider.h \
@@ -160,15 +161,14 @@ spicec_LDFLAGS = \
$(CELT051_LIBS) \
$(SSL_LIBS) \
$(CEGUI_LIBS) \
+ $(JPEG_LIBS) \
$(SPICE_NONPKGCONFIG_LIBS)
spicec_LDADD = \
$(PIXMAN_LIBS) \
- $(FFMPEG_LIBS) \
$(ALSA_LIBS) \
$(GL_LIBS) \
$(XRANDR_LIBS) \
$(MISC_X_LIBS) \
$(CEGUI_LIBS) \
-lrt
-
diff --git a/configure.ac b/configure.ac
index c68d849e..c75a16d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -224,6 +224,19 @@ AS_IF([test "$_cxxflags_is_set" = "yes"], [], [
CXXFLAGS="-g -O2"
])
+AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
+ AC_MSG_CHECKING([for jpeglib.h])
+ AC_TRY_CPP(
+[#include <stdio.h>
+#undef PACKAGE
+#undef VERSION
+#undef HAVE_STDLIB_H
+#include <jpeglib.h>],
+ JPEG_LIBS='-ljpeg'
+ AC_MSG_RESULT($jpeg_ok),
+ AC_MSG_ERROR([jpeglib.h not found])),
+ AC_MSG_ERROR([libjpeg not found]))
+AC_SUBST(JPEG_LIBS)
dnl ===========================================================================
dnl check compiler flags