[FFmpeg-devel] [PATCHv4] VP4 video decoder
Tomas Härdin
tjoppen at acc.umu.se
Tue May 21 12:34:34 EEST 2019
tis 2019-05-21 klockan 17:44 +1000 skrev Peter Ross:
> ---
>
> what's changed:
> * apply #if CONFIG_VP4_DECODER around large vp4 code blocks
> * improved vp4_read_mb_value thanks to reminars suggestions
> * improved configure vp3_decoder_select
>
> [...]
>
> +#define BLOCK_X (2 * mb_x + (k & 1))
> +#define BLOCK_Y (2 * mb_y + (k >> 1))
> +
> +#if CONFIG_VP4_DECODER
> +static int vp4_read_mb_value(GetBitContext *gb)
> +{
> + int v = 1;
> + int bits = show_bits(gb, 9);
This call to show_bits() looks unnecessary
> + while ((bits = show_bits(gb, 9)) == 0x1ff) {
> + skip_bits(gb, 9);
> + v += 256;
> + }
I have a feeling this loop should have a stop condition like v <
SOME_LARGE_VALUE, say INT_MAX-255 or yuv_macroblock_count, to reject
corrupt/malicious files and not cause undefined behavior
> + if (bits < 0x100) {
> + skip_bits(gb, 1);
> + } else if (bits < 0x180) {
> + skip_bits(gb, 2);
> + v += 1;
> + }
> +#define body(n) { \
> + skip_bits(gb, 2 + n); \
> + v += (1 << n) + get_bits(gb, n); }
> +#define else_if(thresh, n) else if (bits < thresh) body(n)
> + else_if(0x1c0, 1)
> + else_if(0x1e0, 2)
> + else_if(0x1f0, 3)
> + else_if(0x1f8, 4)
> + else_if(0x1fc, 5)
> + else_if(0x1fe, 6)
> + else body(7)
> +#undef body
> +#undef else_if
> + return v;
> +}
> @@ -1012,8 +1214,8 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
> bits_to_get = coeff_get_bits[token];
> if (bits_to_get)
> bits_to_get = get_bits(gb, bits_to_get);
> - coeff = coeff_tables[token][bits_to_get];
>
> + coeff = coeff_tables[token][bits_to_get];
Stray hunk
> +#if CONFIG_VP4_DECODER
> + if (s->version >= 2) {
> + int mb_height, mb_width;
> + int mb_width_mul, mb_width_div, mb_height_mul, mb_height_div;
> +
> + mb_height = get_bits(&gb, 8);
> + mb_width = get_bits(&gb, 8);
> + if (mb_height != s->macroblock_height ||
> + mb_width != s->macroblock_width)
> + av_log(s->avctx, AV_LOG_WARNING, "VP4 header: Warning, macroblock dimension mismatch");
> +
> + mb_width_mul = get_bits(&gb, 5);
> + mb_width_div = get_bits(&gb, 3);
> + mb_height_mul = get_bits(&gb, 5);
> + mb_height_div = get_bits(&gb, 3);
> + if (mb_width_mul != 1 || mb_width_div != 1 || mb_height_mul != 1 || mb_height_div != 1)
> + av_log(s->avctx, AV_LOG_WARNING, "VP4 header: Warning, unexpected macroblock dimension multipler/divider");
> +
> + if (get_bits(&gb, 2))
> + av_log(s->avctx, AV_LOG_WARNING, "VP4 header: Warning, unknown bits set");
Maybe these should be errors and/or requests for samples? It macroblock
count changes that may indicate a resolution change
/Tomas
More information about the ffmpeg-devel
mailing list