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

Kostya kostya.shishkov
Thu Mar 19 05:28:44 CET 2009


On Wed, Mar 18, 2009 at 04:25:20PM -0400, Ronald S. Bultje wrote:
> Hi,
> 
> I'm gonna keep trying, just so I learn to not be an idiot. If you want
> me to stop, just say so and I'll commit that first version.
> 
> On Tue, Mar 17, 2009 at 11:57 PM, Kostya <kostya.shishkov at gmail.com> wrote:
> > On Tue, Mar 17, 2009 at 05:34:01PM -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 LOOP_ITER {
> >> + ? ? ? ? ? ?int shift1 = (i & 1) ? 4 : 0, shift2 = (i & 1) ? 0 : 4;
> >> + ? ? ? ? ? ?buf[i >> 1] = (buf[i >> 1] & mask2) |
> >> + ? ? ? ? ? ? ? ?(((buf[o >> 1] & mask2) << shift1) >> shift2);
> >> + ? ? ? ? ? ?buf[o >> 1] = (buf[o >> 1] & mask1) | ((tmp << shift2) >> shift1);
> >> + ? ? ? ?} LOOP_END;
> >
> > No, that still looks like some suspicious condition.
> > You'd better write it without macroses.
> 
> OK, I rewrote it without the (slow) loops. I tried to unroll the loops
> in such a way that as little work as possible is done within the
> loops. Please let me know if I'm showing improvements. :-).
> 
> Ronald

[...]
> @@ -637,6 +661,65 @@
>      }
>  }
>  
> +/** perform 4-bit block reordering for SIPR data */
> +static void
> +rm_reorder_sipr_data (RMStream *ast)
> +{
> +    int n, bs = ast->sub_packet_h * ast->audio_framesize * 2 / 96; // nibbles per subpacket
> +
> +    for (n = 0; n < 38; n++) {
> +        int j;
> +        int i = bs * sipr_swaps[n][0];
> +        int o = bs * sipr_swaps[n][1];
> +        uint8_t *buf = ast->pkt.data;
> +
> +        /* swap 4bit-nibbles of block 'i' with 'o' */
> +        if (!((i ^ o) & 1)) {
> +            int bytes = (bs - (i & 1)) >> 1;
> +            char t[bytes];
> +            if ((i ^ bs) & 1) { /* last 4bits, if unaligned */
> +                int tmp = buf[(i + bs - 1) >> 1] & 0x0F;
> +                buf[(i + bs - 1) >> 1] = (buf[i >> 1] & 0xF0) |
> +                    (buf[(o + bs - 1) >> 1] & 0x0F);
> +                buf[o >> 1] = (buf[(o + bs - 1) >> 1] & 0xF0) | tmp;
> +            }
> +            if (i & 1) { /* first 4 bits, if unaligned */
> +                int tmp = buf[i >> 1] & 0xF0;
> +                buf[i >> 1] = (buf[i >> 1] & 0x0F) | (buf[o >> 1] & 0xF0);
> +                buf[o >> 1] = (buf[o >> 1] & 0x0F) | tmp;
> +                i++; o++;
> +            }
> +            memcpy(&t,           &buf[i >> 1], bytes);
> +            memcpy(&buf[i >> 1], &buf[o >> 1], bytes);
> +            memcpy(&buf[o >> 1], &t,           bytes);
> +        } else {
> +            int mask1, mask2, shift1, shift2, tmp;
> +
> +            mask1  = (i & 1) ? 0xF0 : 0x0F;
> +            mask2  = (i & 1) ? 0x0F : 0xF0;
> +            shift1 = (i & 1) ?    4 :    0;
> +            shift2 = (i & 1) ?    0 :    4;
> +            for (j = 0; j < bs; j+=2, i+=2, o+=2) {
> +                tmp = buf[i >> 1] & mask1;
> +                buf[i >> 1] = (buf[i >> 1] & mask2) |
> +                    (((buf[o >> 1] & mask2) << shift1) >> shift2);
> +                buf[o >> 1] = (buf[o >> 1] & mask1) |
> +                    ((tmp << shift2) >> shift1);
> +            }
> +            i -= j - 1; o-= j - 1;
> +            tmp = mask1;  mask1 = mask2;   mask2 = tmp;
> +            tmp = shift1; shift1 = shift2; shift2 = tmp;
> +            for (j = 1; j < bs; j+=2, i+=2, o+=2) {
> +                tmp = buf[i >> 1] & mask1;
> +                buf[i >> 1] = (buf[i >> 1] & mask2) |
> +                    (((buf[o >> 1] & mask2) << shift1) >> shift2);
> +                buf[o >> 1] = (buf[o >> 1] & mask1) |
> +                    ((tmp << shift2) >> shift1);
> +            }
> +        }
> +    }
> +}
> +
>  int
>  ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb,
>                      AVStream *st, RMStream *ast, int len, AVPacket *pkt,

Well, you are definitely showing progress. I can hardly understand what
this code does.

Please replace it with the first version (one loop) and commit.
I fear it would take long to improve it while the rest is fine.




More information about the ffmpeg-devel mailing list