[FFmpeg-devel] [PATCH] lavc/mjpegdec: hint next marker position in ff_mjpeg_find_marker
Matthieu Bouron
matthieu.bouron at gmail.com
Thu Jan 26 18:47:51 EET 2017
Speeds up next marker search when a SOS marker is found.
ff_mjpeg_find_marker goes from 54% to 30% under perf record ffmpeg -i
sample_2992x4000.jpg
---
libavcodec/mjpegdec.c | 31 +++++++++++++++++++++++++------
libavcodec/mjpegdec.h | 2 +-
libavcodec/mxpegdec.c | 5 +++--
3 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 7d17e3dfcb..29f40cb4e6 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1921,13 +1921,23 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
/* return the 8 bit start code value and update the search
state. Return -1 if no start code found */
-static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
+static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_hint, const uint8_t *buf_end)
{
const uint8_t *buf_ptr;
unsigned int v, v2;
int val;
int skipped = 0;
+ if (buf_hint && (buf_end - buf_hint > 1)) {
+ v = *buf_hint++;
+ v2 = *buf_hint;
+ if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_hint < buf_end) {
+ buf_ptr = buf_hint++;
+ val = v2;
+ goto found;
+ }
+ }
+
buf_ptr = *pbuf_ptr;
while (buf_end - buf_ptr > 1) {
v = *buf_ptr++;
@@ -1947,12 +1957,15 @@ found:
}
int ff_mjpeg_find_marker(MJpegDecodeContext *s,
- const uint8_t **buf_ptr, const uint8_t *buf_end,
+ const uint8_t **buf_ptr,
+ const uint8_t **buf_hint,
+ const uint8_t *buf_end,
const uint8_t **unescaped_buf_ptr,
int *unescaped_buf_size)
{
int start_code;
- start_code = find_marker(buf_ptr, buf_end);
+ start_code = find_marker(buf_ptr, *buf_hint, buf_end);
+ *buf_hint = NULL;
av_fast_padded_malloc(&s->buffer, &s->buffer_size, buf_end - *buf_ptr);
if (!s->buffer)
@@ -1963,6 +1976,7 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s,
const uint8_t *src = *buf_ptr;
const uint8_t *ptr = src;
uint8_t *dst = s->buffer;
+ const uint8_t *next_marker = NULL;
#define copy_data_segment(skip) do { \
ptrdiff_t length = (ptr - src) - (skip); \
@@ -1999,8 +2013,10 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s,
if (x < 0xd0 || x > 0xd7) {
copy_data_segment(1);
- if (x)
+ if (x) {
+ next_marker = ptr - 2;
break;
+ }
}
}
}
@@ -2009,6 +2025,8 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s,
}
#undef copy_data_segment
+ if (next_marker)
+ *buf_hint = next_marker;
*unescaped_buf_ptr = s->buffer;
*unescaped_buf_size = dst - s->buffer;
memset(s->buffer + *unescaped_buf_size, 0,
@@ -2073,7 +2091,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
MJpegDecodeContext *s = avctx->priv_data;
- const uint8_t *buf_end, *buf_ptr;
+ const uint8_t *buf_end, *buf_hint, *buf_ptr;
const uint8_t *unescaped_buf_ptr;
int hshift, vshift;
int unescaped_buf_size;
@@ -2087,10 +2105,11 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
s->adobe_transform = -1;
buf_ptr = buf;
+ buf_hint = NULL;
buf_end = buf + buf_size;
while (buf_ptr < buf_end) {
/* find start next marker */
- start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end,
+ start_code = ff_mjpeg_find_marker(s, &buf_ptr, &buf_hint, buf_end,
&unescaped_buf_ptr,
&unescaped_buf_size);
/* EOF */
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index fb811294a1..c9d289187b 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -144,7 +144,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s,
const uint8_t *mb_bitmask,int mb_bitmask_size,
const AVFrame *reference);
int ff_mjpeg_find_marker(MJpegDecodeContext *s,
- const uint8_t **buf_ptr, const uint8_t *buf_end,
+ const uint8_t **buf_ptr, const uint8_t **buf_hint, const uint8_t *buf_end,
const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size);
#endif /* AVCODEC_MJPEGDEC_H */
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 2e3ebe6e70..28a479a3b5 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -189,18 +189,19 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
int buf_size = avpkt->size;
MXpegDecodeContext *s = avctx->priv_data;
MJpegDecodeContext *jpg = &s->jpg;
- const uint8_t *buf_end, *buf_ptr;
+ const uint8_t *buf_end, *buf_hint, *buf_ptr;
const uint8_t *unescaped_buf_ptr;
int unescaped_buf_size;
int start_code;
int ret;
buf_ptr = buf;
+ buf_hint = NULL;
buf_end = buf + buf_size;
jpg->got_picture = 0;
s->got_mxm_bitmask = 0;
while (buf_ptr < buf_end) {
- start_code = ff_mjpeg_find_marker(jpg, &buf_ptr, buf_end,
+ start_code = ff_mjpeg_find_marker(jpg, &buf_ptr, &buf_hint, buf_end,
&unescaped_buf_ptr, &unescaped_buf_size);
if (start_code < 0)
goto the_end;
--
2.11.0
More information about the ffmpeg-devel
mailing list