diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 2 | ||||
-rw-r--r-- | client/display_channel.cpp | 175 | ||||
-rw-r--r-- | client/mjpeg_decoder.cpp | 236 | ||||
-rw-r--r-- | client/mjpeg_decoder.h | 72 | ||||
-rw-r--r-- | client/windows/redc.vcproj | 16 | ||||
-rw-r--r-- | client/x11/Makefile.am | 16 |
6 files changed, 354 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;"..\..\common\win\my_getopt-1.5";"$(SPICE_LIBS)\include";"$(SPICE_LIBS)\include\pixman-1";"$(SPICE_LIBS)\include\ffmpeg";"$(SPICE_LIBS)\include\CEGUI-0.6.2""
+ AdditionalIncludeDirectories=".;..;..\..\common;..\..\..\spice-protocol;..\..\common\win;"..\..\common\win\my_getopt-1.5";"$(SPICE_LIBS)\include";"$(SPICE_LIBS)\include\pixman-1";"$(SPICE_LIBS)\include\CEGUI-0.6.2""
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=""$(SPICE_LIBS)\lib""
@@ -124,7 +124,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".;..;..\..\..\spice-protocol;..\..\common;..\..\common\win;"..\..\common\win\my_getopt-1.5";"$(SPICE_LIBS)\include";"$(SPICE_LIBS)\include\pixman-1";"$(SPICE_LIBS)\include\ffmpeg";"$(SPICE_LIBS)\include\CEGUI-0.6.2""
+ AdditionalIncludeDirectories=".;..;..\..\..\spice-protocol;..\..\common;..\..\common\win;"..\..\common\win\my_getopt-1.5";"$(SPICE_LIBS)\include";"$(SPICE_LIBS)\include\pixman-1";"$(SPICE_LIBS)\include\CEGUI-0.6.2""
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=""$(SPICE_LIBS)\lib""
@@ -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 - |