diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-04-14 11:41:37 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-04-14 11:41:37 +0200 |
commit | 5a1f8bafa09a8e937b7093b3ecc7b70322b691df (patch) | |
tree | 26bb51de92b5f1e566c03d0fed4a50171253b052 | |
parent | c97116aeb925dfa10420ca8baae1d445da23b73d (diff) | |
download | spice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.tar.gz spice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.tar.xz spice-5a1f8bafa09a8e937b7093b3ecc7b70322b691df.zip |
Avoid unncessary buffer management in mjpeg decoder if possible
-rw-r--r-- | client/mjpeg_decoder.cpp | 64 | ||||
-rw-r--r-- | client/mjpeg_decoder.h | 1 |
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; |