avcodec/vc1: Introduce fast path for unescaping bitstream buffer

Includes a checkasm test.

Signed-off-by: Ben Avison <bavison@riscosopen.org>
Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Ben Avison 2022-03-31 18:23:45 +01:00 committed by Martin Storsjö
parent bd3615a81a
commit 2e26847780
4 changed files with 82 additions and 10 deletions

View file

@ -491,7 +491,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
size = next - start - 4;
if (size <= 0)
continue;
buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
buf2_size = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
init_get_bits(&gb, buf2, buf2_size * 8);
switch (AV_RB32(start)) {
case VC1_CODE_SEQHDR:
@ -681,7 +681,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
case VC1_CODE_FRAME:
if (avctx->hwaccel)
buf_start = start;
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
break;
case VC1_CODE_FIELD: {
int buf_size3;
@ -698,8 +698,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
ret = AVERROR(ENOMEM);
goto err;
}
buf_size3 = vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
slices[n_slices].mby_start = avctx->coded_height + 31 >> 5;
@ -710,7 +710,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
break;
}
case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
init_get_bits(&s->gb, buf2, buf_size2 * 8);
ff_vc1_decode_entry_point(avctx, v, &s->gb);
break;
@ -727,8 +727,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
ret = AVERROR(ENOMEM);
goto err;
}
buf_size3 = vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);
@ -762,7 +762,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
ret = AVERROR(ENOMEM);
goto err;
}
buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf);
buf_size3 = v->vc1dsp.vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf);
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
slices[n_slices].mby_start = s->mb_height + 1 >> 1;
@ -771,9 +771,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
n_slices1 = n_slices - 1;
n_slices++;
}
buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);
buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, divider - buf, buf2);
} else {
buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);
buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, buf_size, buf2);
}
init_get_bits(&s->gb, buf2, buf_size2*8);
} else{

View file

@ -34,6 +34,7 @@
#include "rnd_avg.h"
#include "vc1dsp.h"
#include "startcode.h"
#include "vc1_common.h"
/* Apply overlap transform to horizontal edge */
static void vc1_v_overlap_c(uint8_t *src, ptrdiff_t stride)
@ -1030,6 +1031,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext *dsp)
#endif /* CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER */
dsp->startcode_find_candidate = ff_startcode_find_candidate_c;
dsp->vc1_unescape_buffer = vc1_unescape_buffer;
if (ARCH_AARCH64)
ff_vc1dsp_init_aarch64(dsp);

View file

@ -80,6 +80,9 @@ typedef struct VC1DSPContext {
* one or more further zero bytes and a one byte.
*/
int (*startcode_find_candidate)(const uint8_t *buf, int size);
/* Copy a buffer, removing startcode emulation escape bytes as we go */
int (*vc1_unescape_buffer)(const uint8_t *src, int size, uint8_t *dst);
} VC1DSPContext;
void ff_vc1dsp_init(VC1DSPContext* c);