[FFmpeg-devel] [PATCH] avcodec: add MagicYUV decoder

Christophe Gisquet christophe.gisquet at gmail.com
Mon May 30 14:19:50 CEST 2016


Hi,

2016-05-29 21:51 GMT+02:00 Paul B Mahol <onemda at gmail.com>:
> +typedef struct Slice {
> +    uint32_t start;
> +    uint32_t size;
> +} Slice;

I'm not a security expert, but is there a reason for not using plain int there ?

> +typedef struct MagicYUVContext {
> +    AVFrame            *p;
> +    int                 slice_height;
> +    int                 nb_slices;
> +    int                 planes;
> +    uint8_t             *buf;
> +    int                 hshift[4];
> +    int                 vshift[4];
> +    Slice               *slices[4];
> +    int                 slices_size[4];
> +    uint8_t             freq[4][256];
> +    VLC                 vlc[4];
> +    HuffYUVDSPContext   hdsp;
> +} MagicYUVContext;

I guess someone able to understand the code immediately understand
what those are, but that's pretty sparse comment-wise.

> +typedef struct HuffEntry {

And another Huffman+prediction codec... I don't really see any
valuable addition here... :(

> +    uint8_t  sym;
> +    uint8_t  len;
> +    uint32_t code;
> +} HuffEntry;
> +
> +static int ff_magy_huff_cmp_len(const void *a, const void *b)
> +{
> +    const HuffEntry *aa = a, *bb = b;
> +    return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
> +}
> +
> +static int build_huff(VLC *vlc, uint8_t *freq)
> +{
> +    HuffEntry he[256];
> +    uint32_t codes[256];
> +    uint8_t bits[256];
> +    uint8_t syms[256];
> +    uint32_t code;
> +    int i, last;
> +
> +    for (i = 0; i < 256; i++) {
> +        he[i].sym = 255 - i;
> +        he[i].len = freq[i];
> +    }
> +    qsort(he, 256, sizeof(*he), ff_magy_huff_cmp_len);

ffmpeg seems to have libavutil/qsort.h, but I don't even know how much
effort is needed to use it here.

> +        pred = get_bits(&b, 8);
> +        dst = p->data[i] + j * sheight * stride;
> +        for (k = 0; k < height; k++) {
> +            for (x = 0; x < width; x++) {
> +                int pix;
> +                if (get_bits_left(&b) <= 0) {
> +                    return AVERROR_INVALIDDATA;
> +                }
> +                pix = get_vlc2(&b, s->vlc[i].table, s->vlc[i].bits, 3);
> +                if (pix < 0) {
> +                    return AVERROR_INVALIDDATA;
> +                }
> +                dst[x] = 255 - pix;
> +            }
> +            dst += stride;
> +        }
> +
> +        if (pred == LEFT) {
> +            dst = p->data[i] + j * sheight * stride;
> +            s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
> +            dst += stride;
> +            for (k = 1; k < height; k++) {
> +                s->hdsp.add_hfyu_left_pred(dst, dst, width, dst[-stride]);
> +                dst += stride;
> +            }
> +        } else if (pred == GRADIENT) {
[...]

That's somewhat similar to png paeth, except not actually reusable. I
wonder if there's something in libavcodec that could be reused, in
which case moving it to the hdsp context would be nice)

> +        } else if (pred == MEDIAN) {
[...]
> +        } else {

So, that's maybe a detail at this point, and you want to move quickly
to other stuff, but:
would you like to look at e.g. huffyuvdec or pngdec for a code that is
not as nice looking, but more cache-friendly?

Basically, you move the first line out of the loops, and then do
sequentially, per row in the loop, bitstream reading, reconstruction
(residual+prediction) and any post-processing...

> +    if (decorrelate) {
> +        uint8_t *b = p->data[0];
> +        uint8_t *g = p->data[1];
> +        uint8_t *r = p->data[2];
> +
> +        for (i = 0; i < p->height; i++) {
> +            for (x = 0; x < p->width; x++) {
> +                b[x] += g[x];
> +                r[x] += g[x];
> +            }
> +            b += p->linesize[0];
> +            g += p->linesize[1];
> +            r += p->linesize[2];
> +        }
> +    }

... in particular, this step, that could be done line-wise, inside the
threaded decoding, if I'm not mistaken. (cf. also png's deloco)

Otherwise, I don't see much of anything that would require another
reviewing round.
-- 
Christophe


More information about the ffmpeg-devel mailing list