[FFmpeg-devel] rmdec.c: add SIPR codec try #2

Reimar Döffinger Reimar.Doeffinger
Tue Mar 17 20:21:43 CET 2009


On Tue, Mar 17, 2009 at 02:29:03PM -0400, Ronald S. Bultje wrote:
> +        /* swap 4bit-nibbles of block 'i' with 'o' */
> +        if (!((i ^ o) & 1)) LOOP_ITER {
> +            buf[i >> 1] = (buf[i >> 1] & mask2) | (buf[o >> 1] & mask1);
> +            buf[o >> 1] = (buf[o >> 1] & mask2) | tmp;
> +        } LOOP_END else if (i & 1) LOOP_ITER {
> +            buf[i >> 1] = (buf[i >> 1] & mask2) | ((buf[o >> 1] & mask2) << 4);
> +            buf[o >> 1] = (buf[o >> 1] & mask1) | (tmp >> 4);
> +        } LOOP_END else /* o & 1 */ LOOP_ITER {
> +            buf[i >> 1] = (buf[i >> 1] & mask2) | ((buf[o >> 1] & mask2) >> 4);
> +            buf[o >> 1] = (buf[o >> 1] & mask1) | (tmp << 4);
> +        } LOOP_END;

That's simply wrong, for the ((i ^ o) & 1) case you will alternate
between i & 1 and not, so you can't move that check out of the loop.
Also since it does not matter which is i and which is o (bad naming btw.
IMO, since it implies one is input and one is output while they are
symmetric) you can reduce it to one case by swapping them appropriately
(one conditional swap before, one inside the loop.
If performance is relevant this can of course be optimized a lot, e.g.
using using memcpy for the !((i ^ o) & 1) case except the first and last
byte, and doing two swaps per iteration for the other case to avoid
swapping i and o.




More information about the ffmpeg-devel mailing list