[FFmpeg-devel] [PATCH] RoQ video encoder, take 2

Reimar Döffinger Reimar.Doeffinger
Sun May 27 13:21:14 CEST 2007


Hello,
On Sun, May 27, 2007 at 12:21:03PM +0200, Vitor wrote:
> +#define SQUARE(x) ((x)*(x))

I think you are using this always on the same kinds of data, so I'd
consider making this a static inline function, at low optimization
levels this would avoid evaluating x twice.

> +typedef struct
> +{
> +    roq_cell block[4];
> +} roq_cell4;

Hmm.. Did you compare this both in code complexity and speed to just
using roq_cell *a or roq_cell a[4]?

> +typedef struct
> +{
> +    uint32_t eval_se[4];
> +
> +    uint8_t subCels[4];
> +
> +    int8_t motionX, motionY;
> +    uint8_t cbEntry;
> +} roq_subcel_evaluation_t;
> +
> +typedef struct
> +{
> +    uint32_t eval_se[3];
> +
> +    roq_subcel_evaluation_t subCels[4];
> +
> +    int8_t motionX, motionY;
> +    uint8_t cbEntry;
> +
> +    uint32_t sourceX, sourceY;
> +} cel_evaluation_t;

Unless there is a special reason not to, try using just "int" instead of
"int8_t".

> +/**
> + * 4*4*4*4 subdivide types + 3 non-subdivide main types
> + */
> +#define ROQ_MAX_POSSIBILITIES    259

Then why not just
> +#define ROQ_MAX_POSSIBILITIES    (4*4*4*4+3)

> +#define COPY_SINGLE_BLOCK(BLOCK, DATA, TOP, LEFT, LINEW, LINEWU, LINEWV)\
> +    do { \
> +        (BLOCK).y[0] = (DATA)[0][(TOP  )*(LINEW )   + LEFT    ]; \
> +        (BLOCK).y[1] = (DATA)[0][(TOP  )*(LINEW )   + LEFT + 1]; \
> +        (BLOCK).y[2] = (DATA)[0][(TOP+1)*(LINEW )   + LEFT    ]; \
> +        (BLOCK).y[3] = (DATA)[0][(TOP+1)*(LINEW )   + LEFT + 1]; \
> +        (BLOCK).u    = (DATA)[1][(TOP  )*(LINEWU)/2 + (LEFT)/2]; \
> +        (BLOCK).v    = (DATA)[2][(TOP  )*(LINEWV)/2 + (LEFT)/2]; \
> +    } while(0)

Does using a macro have a real advantage over a static inline function?
And also, since DATA is an array, why not use LINEW as an array as well
instead of split into LINEW, LINEWU and LINEWV?
I think some other macros could be converted into functions as well.

> +    /* Sort primarily by validity */
> +    if (!so1[0]->valid) {
> +        if (!so2[0]->valid)
> +            return 0;
> +        else
> +            return 1;

return !so2[0]->valid;

> +    if ((avctx->width & 0xf) || (avctx->height & 0xf)) {
> +        av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n");
> +        return -1;
> +    }
> +
> +    if (((avctx->width)&(avctx->width-1)) ||
> +        ((avctx->height)&(avctx->height-1)))
> +        av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two\n");
> +
> +    if ((avctx->width > 65535) || (avctx->height > 65535))  {
> +        av_log(avctx, AV_LOG_ERROR, "Dimension must be each < 65536\n");
> +        return -1;
> +    }
> +
> +    if ((avctx->width == 0)  || (avctx->height == 0)) {
> +        av_log(avctx, AV_LOG_ERROR, "Dimensions can not be null\n");
> +        return -1;
> +    }

Lots of useless (), I also think you should probably use
avcodec_check_dimensions somewhere.

[...]
> +#define get_word(in_buffer) ((unsigned short)(in_buffer += 2, \
> +  (in_buffer[-1] << 8 | in_buffer[-2])))
> +#define get_long(in_buffer) ((unsigned long)(in_buffer += 4, \
> +  (in_buffer[-1] << 24 | in_buffer[-2] << 16 | in_buffer[-3] << 8 | in_buffer[-4])))

I don't think these are valid C.
Are these so speed critical that you can't use bytestream functions?

> +    for(i = -512; i < 512; i++)
> +        s->uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i));

av_clip_uint8 ?

Hmm... these seem to be there in the current code already though...

[...]
> +    AVFrame *last_frame;
> +    AVFrame *current_frame;
> +
> +    uint8_t **last_frame_data;
> +    uint8_t **current_frame_data;

Are these two really needed, can't you just use the AVFrames above as in
the decoder?
At least they should be uint8_t *last_frame_data[3]; IMO, thus avoiding
an extra malloc and indirection step on access. I don't think it matters
much if you copy 4/8 or 12/24 bytes on swapping them.

Greetings,
Reimar D?ffinger




More information about the ffmpeg-devel mailing list