diff options
author | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2016-01-26 17:15:37 +0100 |
---|---|---|
committer | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2016-01-27 20:08:52 +0100 |
commit | 0d733ec3794d6854377ad0be159d9c1475edae01 (patch) | |
tree | 6acb8e832148f9c8527193f18ea25662918b10af /libavcodec | |
parent | e5b5676c008552e7602789cc80c99887d2b33504 (diff) | |
download | ffmpeg-0d733ec3794d6854377ad0be159d9c1475edae01.tar.gz |
lavc/mjpegdec: speed up scan data copy
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/mjpegdec.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 77a1ac2a59..0aedc9dae7 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1921,24 +1921,54 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, /* unescape buffer of SOS, use special treatment for JPEG-LS */ if (start_code == SOS && !s->ls) { const uint8_t *src = *buf_ptr; + const uint8_t *ptr = src; uint8_t *dst = s->buffer; - while (src < buf_end) { - uint8_t x = *(src++); + #define copy_data_segment(skip) do { \ + ssize_t length = (ptr - src) - (skip); \ + if (length > 0) { \ + memcpy(dst, src, length); \ + dst += length; \ + src = ptr; \ + } \ + } while (0) + + if (s->avctx->codec_id == AV_CODEC_ID_THP) { + ptr = buf_end; + copy_data_segment(0); + } else { + while (ptr < buf_end) { + uint8_t x = *(ptr++); - *(dst++) = x; - if (s->avctx->codec_id != AV_CODEC_ID_THP) { if (x == 0xff) { - while (src < buf_end && x == 0xff) - x = *(src++); + ssize_t skip = 0; + while (ptr < buf_end && x == 0xff) { + x = *(ptr++); + skip++; + } - if (x >= 0xd0 && x <= 0xd7) - *(dst++) = x; - else if (x) - break; + /* 0xFF, 0xFF, ... */ + if (skip > 1) { + copy_data_segment(skip); + + /* decrement src as it is equal to ptr after the + * copy_data_segment macro and we might want to + * copy the current value of x later on */ + src--; + } + + if (x < 0xd0 || x > 0xd7) { + copy_data_segment(1); + if (x) + break; + } } } + if (src < ptr) + copy_data_segment(0); } + #undef copy_data_segment + *unescaped_buf_ptr = s->buffer; *unescaped_buf_size = dst - s->buffer; memset(s->buffer + *unescaped_buf_size, 0, |