Hi,

On Wed, Mar 23, 2011 at 2:03 PM, Kostya <[email protected]> wrote:
> On Tue, Mar 22, 2011 at 06:54:38PM +0100, Diego Biurrun wrote:
>> On Sun, Mar 20, 2011 at 11:02:23AM +0100, Kostya wrote:
>> > [...]
>>
>> The usual nits..
>
> reordered, added whitespaces, broke some long lines (even if I don't know what
> to do with all that karma), fixed license and added missing long name

Decoder review:

> +static int which_edge(int x, int y, int edge_size)

s/int/enum GlyphEdge/

> +static int which_direction(int edge0, int edge1)

s/int/enum GlyphDir/

> +static void interp_point(int8_t *ppoint, int x0, int y0, int x1, int y1, int 
> ipoint, int npoints)
> +{
> +    if (npoints) {
> +        ppoint[0] = (x0 * ipoint + x1 * (npoints - ipoint) + (npoints >> 1)) 
> / npoints;
> +        ppoint[1] = (y0 * ipoint + y1 * (npoints - ipoint) + (npoints >> 1)) 
> / npoints;
> +    } else {

I find it hard to see what values npoints typically has, but is using
FASTDIV() an option here?

> +static void init_sizes(sanm_ctx *ctx, int width, int height)
[..]
> +    ctx->aligned_width  = FFALIGN(width,  8);
> +    ctx->aligned_height = FFALIGN(height, 8);

AVCodecContext->coded_width/height?

+static int old_codec1(sanm_ctx *ctx, const uint8_t *src, int size,
+                      int top, int left, int width, int height)

That's a pretty lame function name. Same for the others.

+{
+    uint8_t *dst = ((uint8_t*)ctx->pdb0) + left + top * ctx->pitch;

Spaces (hah!).

v+static int old_codec37(sanm_ctx *ctx, const uint8_t *src, int size,
> +                       int top, int left, int width, int height)
[..]
> +        av_log(ctx->avctx, AV_LOG_ERROR, "Codec 37 compr 1: NIY\n");

IKWTMBMPW.

> +        for (j = 0; j < height; j++) {
> +            memcpy(dst, src, width);
> +            dst += stride;
> +            src += width;

Won't this overread?

(I didn't look at this function in detail, please make sure it doesn't
overread elsewhere, me tired.)

> +static int old_codec47(sanm_ctx *ctx, const uint8_t *orig_src, int size,
> +                       int top, int left, int width, int height)
[..]
+    const uint8_t *src = orig_src + 26, *src_end = orig_src + size;

What is this 26?

> +    if (orig_src[4] & 1)
> +        src += 0x8080;

?? You're just skipping 0x8080 bytes? (Weird.)

> +    switch (compr) {
> +    case 0:

Some comments would help the unsuspecting reader here. E.g. case 0: //
uncompressed block. Same for the others.

> +    case 5:
> +        t = AV_RL32(orig_src + 14);
> +        buf = av_malloc(t+16);
> +        if (!buf)
> +            return -1;

Some checks to make sure "t" is valid would make sense, this could be
a huge malloc bomb in a nicely crafted stream.

> +static int decode_0(sanm_ctx *ctx, const uint8_t *buf, const uint8_t 
> *buf_end)

How about you name these functions more interestingly? decode_<num>
isn't very descriptive. They do distinctly different things, exposing
such information in a function name is a common way to make code
maintainable and readable.

> +    if (ctx->width * ctx->height * 2 > buf_end - buf) {
> +        av_log(ctx->avctx, AV_LOG_ERROR, "Insufficient data for raw 
> frame\n");
> +        return -1;
> +    }
> +    for (y = 0; y < ctx->height; y++) {
> +        for (x = 0; x < ctx->width; x++)
> +            pdb0[x] = bytestream_get_le16(&buf);
> +        pdb0 += ctx->pitch;
> +    }
> +    return 0;
> +}

At the very least you can

#if LITTLE_ENDIAN
memcpy(pdb0, buf, ctx->width*2); buf += ctx->width*2; pdb0 += ctx->pitch;
#else
..

> +static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int 
> pitch)
> +{
> +    int y;
> +
> +    for (y = 0; y != block_size; y++, pdest += pitch, psrc += pitch)
> +        memcpy(pdest, psrc, block_size * sizeof(pdest[0]));
> +}

Isn't this dspcontext.put_pixels_16/8() for block_size=8/4? They would
be faster.

> +static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int 
> pitch)
> +{
> +    int x, y;
> +
> +    pitch -= block_size;
> +    for (y = 0; y != block_size; y++, pdest += pitch)
> +        for (x = 0; x != block_size; x++)
> +            *pdest++ = color;
> +}

I'm actually susprised, but I'd expect one of the h264 prediction
functions to be useful here. No such thing... Ignore this. :-).

> +static int opcode_0xf7(sanm_ctx *ctx, int cx, int cy, int block_size, int 
> pitch)
[..]

This function name can also be better... This is not assembly, you know.

> +        indices = bytestream_get_le32(&ctx->src);
> +        dst[0]         = ctx->codebook[indices & 0xFF]; indices >>= 8;
> +        dst[1]         = ctx->codebook[indices & 0xFF]; indices >>= 8;
> +        dst[pitch]     = ctx->codebook[indices & 0xFF]; indices >>= 8;
> +        dst[pitch + 1] = ctx->codebook[indices & 0xFF];

How is this different from:
dst[0]         = ctx->codebook[*ctx->src++];
dst[1]         = ctx->codebook[*ctx->src++];
dst[pitch]     = ctx->codebook[*ctx->src++];
dst[pitch + 1] = ctx->codebook[*ctx->src++];
? That looks more readable to me.

> +static int good_mvec(sanm_ctx *ctx, int cx, int cy, int mx, int my, int 
> block_size)
> +{
> +    int start_pos = cx + mx + (cy + my) * ctx->pitch;
> +    int end_pos = start_pos + (block_size - 1) * (ctx->pitch + 1);
> +
> +    int good = start_pos >= 0 && end_pos < (ctx->buf_size >> 1);
> +
> +    if (!good) {
> +        av_log(ctx->avctx, AV_LOG_ERROR, "ignoring invalid motion vector 
> (%i, %i)->(%u, %u), block size = %u.\n",
> +               cx + mx, cy + my, cx, cy, block_size);
> +    }
> +
> +    return good;
> +}

An alternative is to clip it if it's not good. Then at least the frame
data is not uninitialized, although I agree that there's still a good
chance that you get garbage out of it...

> +static int decode_5(sanm_ctx *ctx, const uint8_t *buf, const uint8_t 
> *buf_end)
[..]
> +    if (HAVE_BIGENDIAN) {
> +        while (npixels--) {
> +            *pdb0 = av_bswap16(*pdb0);
> +            pdb0++;
> +        }
> +    }

Use the dsputil function Mans just created for AC3.

> +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, 
> AVPacket *pkt)
[..]
> +    if (!ctx->version) {

Any reason these aren't two decoders? I don't see them sharing a lot
of common code, and if they do share some, it can be split over 3
files. Makes review also much simpler. :-).

> +        while (src < src_end - 8) {
> +            int sig, size;

uint32_t.

> +            if (size < 0 || src_end - src < size) {
> +                av_log(avctx, AV_LOG_ERROR, "Incorrect chunk size %d\n", 
> size);
> +                break;
> +            }

And then size < 0 condition is not needed.

> +            case MKBETAG('X', 'P', 'A', 'L'):
[..]
> +                if (size == 6 || size == 4) {
[..]
> +                } else {
> +                    const uint8_t *psrc = src + 4;

Any idea what these 4 btyes are that you're skipping here?

> +            case MKBETAG('S', 'T', 'O', 'R'):
> +                to_store = 1;
> +                break;
> +            case MKBETAG('F', 'T', 'C', 'H'):
> +                memcpy(ctx->pdb0, ctx->stored_frame, ctx->buf_size);
> +                break;
[..]
> +        if (to_store)
> +            memcpy(ctx->stored_frame, ctx->pdb0, ctx->buf_size);
> +        copy_output(ctx, NULL);
> +        memcpy(ctx->output->data[1], ctx->pal, 1024);

So this is very basic handling of P-frames and reference frames? Is
there some way to integrate src_pitch in the writing of pdb0 so you
can use reget_buffer and frame referencing (in AVFrame) instead of the
manual memcpy()s?

(Don't spend too much time on it, it's a game codec, I'm just
wondering how complex it is.)

Also, please set AVFrame.pict_type, that shouldn't be too hard.

Ronald
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to