summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-04-14 11:41:37 +0200
committerAlexander Larsson <alexl@redhat.com>2010-04-14 11:41:37 +0200
commit5a1f8bafa09a8e937b7093b3ecc7b70322b691df (patch)
tree26bb51de92b5f1e566c03d0fed4a50171253b052 /client
parentc97116aeb925dfa10420ca8baae1d445da23b73d (diff)
downloadspice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.tar.gz
spice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.tar.xz
spice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.zip
Avoid unncessary buffer management in mjpeg decoder if possible
Diffstat (limited to 'client')
-rw-r--r--client/mjpeg_decoder.cpp64
-rw-r--r--client/mjpeg_decoder.h1
2 files changed, 46 insertions, 19 deletions
diff --git a/client/mjpeg_decoder.cpp b/client/mjpeg_decoder.cpp
index 21a77a29..42bf2f97 100644
--- a/client/mjpeg_decoder.cpp
+++ b/client/mjpeg_decoder.cpp
@@ -127,28 +127,17 @@ void MJpegDecoder::convert_scanline(void)
}
}
-bool MJpegDecoder::decode_data(uint8_t *data, size_t length)
+void MJpegDecoder::append_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 (length == 0) {
+ return;
}
if (_data_size - _data_end < length) {
- /* Can't fit in tail */
+ /* Can't fits in tail, need to make space */
data_len = _data_end - _data_start;
if (_data_size - data_len < length) {
@@ -168,9 +157,38 @@ bool MJpegDecoder::decode_data(uint8_t *data, size_t length)
memcpy (_data + _data_end, data, length);
_data_end += length;
+}
- _jsrc.next_input_byte = _data + _data_start;
- _jsrc.bytes_in_buffer = _data_end - _data_start;
+bool MJpegDecoder::decode_data(uint8_t *data, size_t length)
+{
+ bool got_picture;
+ int res;
+
+ 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_end - _data_start == 0) {
+ /* No current data, pass in without copy */
+
+ _jsrc.next_input_byte = data;
+ _jsrc.bytes_in_buffer = length;
+ } else {
+ /* Need to combine the new and old data */
+ append_data(data, length);
+
+ _jsrc.next_input_byte = _data + _data_start;
+ _jsrc.bytes_in_buffer = _data_end - _data_start;
+ }
switch (_state) {
case STATE_READ_HEADER:
@@ -232,8 +250,16 @@ bool MJpegDecoder::decode_data(uint8_t *data, size_t length)
break;
}
- _data_start = _jsrc.next_input_byte - _data;
- _data_end = _data_start + _jsrc.bytes_in_buffer;
+ if (_jsrc.next_input_byte == data) {
+ /* We read directly from the user, store remaining data in
+ buffer for next time */
+ size_t read_size = _jsrc.next_input_byte - data;
+
+ append_data(data + read_size, length - read_size);
+ } else {
+ _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
index df7d9319..f435f3f3 100644
--- a/client/mjpeg_decoder.h
+++ b/client/mjpeg_decoder.h
@@ -47,6 +47,7 @@ private:
friend void mjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
void convert_scanline(void);
+ void append_data(uint8_t *data, size_t length);
struct jpeg_decompress_struct _cinfo;
struct jpeg_error_mgr _jerr;